Mac OS 开发

1,应用设置

 @objc func termedApp(){
        //关闭应用
       NSApplication.shared.terminate(nil)
        
    }
    //显示提示角标
    @objc func showAppAlertNum(){
        NSApp.dockTile.badgeLabel = "20"
    }
    //app图标弹跳
    @objc func appshaked(){
        /*
          criticalRequest 多次跳动,直到用户选中app
         
          informationalRequest 一次跳动
         */
        
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 5) {
            //此方法只能当前app处在非活跃状态
            NSApp.requestUserAttention(NSApplication.RequestUserAttentionType.criticalRequest)
        }
       
    }
    //隐藏或者显示dock图标
    @objc func hidOrShowDockIcon(){
        /*
         
         /* The application is an ordinary app that appears in the Dock and may have a user interface.  This is the default for bundled apps, unless overridden in the Info.plist. */
         case regular
         
         
         /* The application does not appear in the Dock and does not have a menu bar, but it may be activated programmatically or by clicking on one of its windows.  This corresponds to LSUIElement=1 in the Info.plist. */
         case accessory
         
         
         /* The application does not appear in the Dock and may not create windows or be activated.  This corresponds to LSBackgroundOnly=1 in the Info.plist.  This is also the default for unbundled executables that do not have Info.plists. */
         case prohibited
         */
        //隐藏dock上的图标,上面的toolbar 也会隐藏
        NSApp.setActivationPolicy(NSApplication.ActivationPolicy.accessory)
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 4) {
            //显示窗口
            NSApp.unhideWithoutActivation()
        }
    
    }
    
    override func viewDidAppear() {
        let window1 = view.window
        //标题
        window1?.title = "测试window"
        //背景色
        window1?.backgroundColor = NSColor.gray
        //设置窗口的按钮关闭和最小化和全屏
        //        window1?.standardWindowButton(NSWindow.ButtonType.closeButton)?.isHidden = true
                window1?.standardWindowButton(NSWindow.ButtonType.zoomButton)?.isHidden = true
        //        window1?.standardWindowButton(NSWindow.ButtonType.miniaturizeButton)?.isHidden = true
        
        //设置窗口显示级别,可以将窗口置顶
        /*
         如果两个window的级别是一样的,就按照出现顺序,后出现的显示最顶层,否则就按照levelz值大小来显示
         
         */
        window1?.level =  NSWindow.Level(rawValue: NSInteger(CGWindowLevelForKey(CGWindowLevelKey.normalWindow)))
        
        //点击窗口背景支持鼠标拖动窗口
        window1?.isMovableByWindowBackground = true
        
        //希望窗口进来是全屏的
//        window1?.toggleFullScreen(window1)
        
        //在Dock中有窗口提示
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+5) {
            window1?.dockTile.badgeLabel = "20"
        }
        
        //设置窗口样式
        
        //不显示窗体边线
        window1?.titlebarAppearsTransparent = true
    
    }

AppDelegate.swift

import Cocoa
/***
 类似main函数入口
 */
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
    var windownum = 0


    func applicationDidFinishLaunching(_ aNotification: Notification) {
        // Insert code here to initialize your application
        //获取窗口号
        guard let win = NSApp.mainWindow else {
            return
        }
        windownum = win.windowNumber
    }

    func applicationWillTerminate(_ aNotification: Notification) {
        // Insert code here to tear down your application
    }
    
    //重新开关应用,
    func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool {
        //如果主窗口已经显示
        if flag == true {
            return flag
        }
        //获取到app,让窗口显示出来
       /*
         NSApp.mainWindow 主窗口
        NSApp.keyWindow 当前窗口
         */
        let window = NSApp.window(withWindowNumber: windownum)
        window?.makeKeyAndOrderFront(nil)
        return true
    }

}

2,常见控件使用

	//开启背景色可编辑
		view.wantsLayer = true
        view.layer?.backgroundColor = NSColor.white.cgColor
        // Do view setup here.
        let button1 = NSButton(frame: NSMakeRect(0, 0, 80, 50))
        button1.title = "点击一下试试"
        button1.alternateTitle = "欢迎再次点击"
        view.addSubview(button1)
        button1.state = NSControl.StateValue.on
        button1.bezelStyle = .rounded
        button1.setButtonType(NSButton.ButtonType.radio)
        button1.image = NSImage(named: "42.png")
        button1.alternateImage = NSImage(named: "39")
        
        button1.target = self
        button1.action = #selector(buttonClicked(sender:))
        button1.tag = 10
        
        
        let imageView = NSImageView(frame: NSMakeRect(20, 150, 40, 40))
        view.addSubview(imageView);
        imageView.image = NSImage(named: "44.png")
        imageView.animates = true
        imageView.isEditable = true
//        imageView.allowsCutCopyPaste = true
        /*
         NSImageFrameNone = 0,
         NSImageFramePhoto,
         NSImageFrameGrayBezel,
         NSImageFrameGroove,
         NSImageFrameButton
         */
        imageView.imageFrameStyle = .photo
        
        //imageview 默认的animation 是 true
        imageView.animates = true
        
        //拖拽效果,苹果推荐使用nsbutton
        
        imageView.target = self
        imageView.action = #selector(clickImageview(_:))
        
        //用户行为操作
        /*1,imageview 上方添加一个按钮*/
        
        /*2 手势操作*/
       let clickGes = NSClickGestureRecognizer(target: self, action: #selector(clickImageViewFor1(_:)))
        GesImageView.addGestureRecognizer(clickGes)
        
        /*3 自定义nNSImageView 重写方法*/
        
        MyImageV.target = self
        MyImageV.action = #selector(clickMyOwnImagView)
        
    }
    @objc func clickMyOwnImagView(){
        print("点击了自定义的imagView")
    }
    @objc func clickImageViewFor1(_ view1:NSControl) -> Void {
        print("使用手势来处理")
    }
    @IBAction func ClickImageAction(_ sender: NSButton) {
        print("点击图片按钮了")
    }
    @objc func clickImageview(_ view:NSImageView) -> Void {
        print("其它文件图片已经拖拽到文件筐里了")
    }
    @objc func buttonClicked(sender : NSButton) -> Void {
        print("Click button")
    }

约束添加,中间有一部分控件是从故事版拉过来的

 mybox.translatesAutoresizingMaskIntoConstraints = false
//        NSLayoutAnchor
        let myViewConts = [
            mybox.topAnchor.constraint(equalTo: view.topAnchor, constant: 20),
            mybox.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20),
            mybox.heightAnchor.constraint(equalToConstant: 20),
            mybox.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -20)
            
        ]
        NSLayoutConstraint.activate(myViewConts)
        mybox.layer?.backgroundColor = NSColor.red.cgColor

        //关闭之前的试图约束
        blueTf.translatesAutoresizingMaskIntoConstraints = false
        //添加约束
        let blueTfConts = [
            blueTf.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -20),
            blueTf.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -50),
            blueTf.heightAnchor.constraint(equalToConstant: 80),
            blueTf.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 100)
        ]
        //激活约束
        NSLayoutConstraint.activate(blueTfConts)
        //设置背景色
        blueTf.layer?.backgroundColor = NSColor.blue.cgColor

3,点击按钮全屏

  	let window1 = self.view.window
         window1?.toggleFullScreen(window1)

4,NSCollectionView 实现流布局
(1),注册单元格,或者头部视图

let headerId :String? = "BOB_Header"
class SevenVc: NSViewController {
//
    @IBOutlet weak var myCollectionView: NSCollectionView!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do view setup here.
        //注册NSCollectionView的Items
       myCollectionView.register( MyCollectionViewItem.self, forItemWithIdentifier: NSUserInterfaceItemIdentifier(rawValue: "ADC"))
        
        //headerView 或者 footerView需要维护
        let headNib = NSNib(nibNamed: "HeadView", bundle: nil)
        myCollectionView.register(headNib, forSupplementaryViewOfKind: (NSCollectionView.elementKindSectionHeader), withIdentifier: NSUserInterfaceItemIdentifier(headerId ?? ""))
        
        (myCollectionView.collectionViewLayout as! NSCollectionViewFlowLayout).sectionHeadersPinToVisibleBounds = true
        
    }
    
}

(2),遵守NSCollectionViewDelegate 和NSCollectionViewDataSource 协议,并且实现协议方法

//数据源
extension SevenVc:NSCollectionViewDataSource{
    //返回每个section中单元格个数
    func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
        return 20
    }
    //section个数
    func numberOfSections(in collectionView: NSCollectionView) -> Int {
        return 2
    }
    
//    func collectionViewItem 的样式
    func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
        let item = collectionView.makeItem(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "ADC"), for: indexPath) as! MyCollectionViewItem
        var imageName:String = "39.png"
        switch ((indexPath.item) % 3) {
        case 0:
            imageName = "39.png"
            break
        case 1:
                imageName = "42.png"
                break
        case 2:
                imageName = "44.png"
                break
            
        default:
            imageName = "39.png"
            break
        }
//        let image = NSImage(named: <#T##NSImage.Name#>)
//        item.mimageView.image = NSImage(byReferencingFile: imageName)
        item.mtitleLab.stringValue = "\(indexPath.item)"
        return item
    }
    //headview和footerView的操作
    func collectionView(_ collectionView: NSCollectionView, viewForSupplementaryElementOfKind kind: NSCollectionView.SupplementaryElementKind, at indexPath: IndexPath) -> NSView {
        let headView = collectionView.makeSupplementaryView(ofKind: NSCollectionView.elementKindSectionHeader, withIdentifier: NSUserInterfaceItemIdentifier(headerId ?? ""), for: indexPath) as! HeaderView
        headView.TitleLab.stringValue = "\(indexPath.section)"
        return headView
    }
    
    
}

//代理的操作
extension SevenVc:NSCollectionViewDelegate{
    //选中操作
    func collectionView(_ collectionView: NSCollectionView, didSelectItemsAt indexPaths: Set<IndexPath>) {
        print("选中操作 ")
    }
    
    //取消选中操作
    func collectionView(_ collectionView: NSCollectionView, didDeselectItemsAt indexPaths: Set<IndexPath>) {
        print("取消选中")
    }
    
}

5 NSAlert 和 NSPopover 提示的使用

import Cocoa

class TwoVc: NSViewController {
    var popVc:NSWindowController?
    
    @IBOutlet weak var btn1: NSButton!
    @IBOutlet weak var btn2: NSButton!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do view setup here.
        btn1.target = self
        btn1.action = #selector(showAlert1)
        btn2.target = self
        btn2.action = #selector(showPopOver)
        
    }
    @objc func showPopOver(){
        let popOver = NSPopover()
        //从故事版加载控制器
        let popoverVc = NSStoryboard(name: "Two", bundle: nil).instantiateController(withIdentifier: "popOverVc") as! NSViewController
        //设置内容控制器
        popOver.contentViewController = popoverVc
        
        popOver.delegate = self
        
        /*
         case applicationDefined 默认值,不会关闭
         
         case transient 点击窗口以外会关闭
         
         case semitransient  点击esc 消失
         
         */
        popOver.behavior = .semitransient
        /*
         显示popover
         relativeTo:popover 三角箭头指向的边界
         of:说明第一个控件的父控件
         preferredEdge:四条边的那一条边界
         */
        popOver.show(relativeTo: view.bounds, of: view, preferredEdge: NSRectEdge.maxY)
        
    }
    @objc func showAlert1(){
        let alert = NSAlert()
        alert.messageText = "提示警告"
        alert.informativeText = "显示提示框详细内容"
        alert.icon = NSImage(named: "warn")
        alert.addButton(withTitle: "按钮1")
        alert.addButton(withTitle: "按钮2")
        let btns = alert.buttons
        for btn in btns {
            print(btn.title)
        }
        
        //代理方法,实现z帮助内容
        alert.delegate = self
        alert.showsHelp = true
        alert.helpAnchor = "帮助内容"
        
        //辅助视图
        alert.layout()
        let imgV = NSImageView(frame: NSMakeRect(0, 0, 100, 100))
        imgV.image = NSImage(named: "beauty")
        alert.accessoryView = imgV
        
        alert.showsSuppressionButton = true
        alert.suppressionButton?.title = "是否不再提示"
        
        
        //关联窗口显示
        alert.beginSheetModal(for: view.window!) { (result) in
            if result == NSApplication.ModalResponse.alertFirstButtonReturn {
                            print("点击了btn1")
                        }
            //是否选中
            print(alert.suppressionButton?.state)
        }
        //独立窗口显示
//        let result = alert.runModal()
//        if result == NSApplication.ModalResponse.alertFirstButtonReturn {
//            print("点击了btn1")
//        }
    }
    
}
//NSAlertDelegate
extension TwoVc:NSAlertDelegate{
    //return false 表示代理自己处理,否则就是系统自己处理
    func alertShowHelp(_ alert: NSAlert) -> Bool {
        //一般跳转帮助页面来提示
        print("点击了帮组选项")
        return false
    }
}

//NSPopoverDelegate
extension TwoVc:NSPopoverDelegate{
    //根据返回值确认窗口是否可以关闭
    func popoverShouldClose(_ popover: NSPopover) -> Bool {
        print("想要关闭窗口")
        return true
    }
    func popoverDidShow(_ notification: Notification) {
         print("显示了")
    }
    func popoverDidClose(_ notification: Notification) {
         print("已经关闭窗口")
    }
    func popoverWillShow(_ notification: Notification) {
         print("将要显示")
    }
    func popoverWillClose(_ notification: Notification) {
         print("将要关闭窗口")
    }
    //支持鼠标拖动
    func popoverShouldDetach(_ popover: NSPopover) -> Bool {
        return true
    }
    func popoverDidDetach(_ popover: NSPopover) {
        print("拖动")
    }
    //拖动时候变成独立window
    func detachableWindow(for popover: NSPopover) -> NSWindow? {
        popVc = NSStoryboard(name: "Two", bundle: nil).instantiateController(withIdentifier: "popwindowVc") as! NSWindowController
        return popVc?.window
    }
}

5,NSMenu菜单使用
(1).app菜单:系统会提供一个默认的菜单
(2).控件右侧显示菜单:应用本身提供一些快捷操作选项,控件左侧也有但是很少用
(3).Dock栏上菜单,系统有默认选项,用户可以自己添加
(4).使用故事板 MainStoryBoard 会有默认menu 可编辑
(5).在StoryBoard的ViewController最上方bar上添加,编辑

//
//  ThreeVc.swift
//  MyMacOsApp1
//
//  Created by syStudio sy on 2019/6/3.
//  Copyright © 2019 syStudio sy. All rights reserved.
//

import Cocoa

/*
 1。app菜单:系统会提供一个默认的菜单
 2,控件右侧显示菜单:应用本身提供一些快捷操作选项,控件左侧也有但是很少用
 3.Dock栏上菜单,系统有默认选项,用户可以自己添加
 
 
 */
class ThreeVc: NSViewController {

    @IBOutlet weak var leftBtnMenu: NSButton!
    @IBOutlet weak var rightBtnMenu: NSButton!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do view setup here.
        rightBtnMenu.target = self
        rightBtnMenu.action = #selector(showRightMenue)
        
        leftBtnMenu.target = self
        leftBtnMenu.action = #selector(showLeftMenue)
        
        //添加系统菜单栏Item
        addAppMenueItem()
    }
    @objc func showRightMenue(){
        let rightMenue = NSMenu(title: "菜单")
        let item = NSMenuItem(title: "功能1", action: #selector(clickItems(Sender:)), keyEquivalent: "")
         let item1 = NSMenuItem(title: "功能2", action: #selector(clickItems(Sender:)), keyEquivalent: "")
         let item2 = NSMenuItem(title: "功能2", action: #selector(clickItems(Sender:)), keyEquivalent: "")
        
        rightMenue.addItem(item)
        rightMenue.addItem(item1)
        rightMenue.addItem(item2)
        //给右键菜单f
        rightBtnMenu.menu = rightMenue
        
    
    }
    @objc func clickItems(Sender:NSMenuItem) -> Void {
        print("\(Sender.title)")
    }
    //添加左键菜单
    @objc func showLeftMenue(){
        let menu  = NSMenu(title: "左键")
        let item = NSMenuItem(title: "功能1", action: #selector(clickItems(Sender:)), keyEquivalent: "")
         let item1 = NSMenuItem(title: "功能2", action: #selector(clickItems(Sender:)), keyEquivalent: "")
         let item2 = NSMenuItem(title: "功能3", action: #selector(clickItems(Sender:)), keyEquivalent: "")
        menu.addItem(item)
        menu.addItem(item1)
        menu.addItem(item2)
        //绑定事件
        NSMenu.popUpContextMenu(menu, with: NSApp.currentEvent!, for: leftBtnMenu)
        
    }
    //在app菜单栏添加
    func addAppMenueItem() -> Void {
        //1.获取app菜单
        let menu = NSApp.mainMenu
        //2.创建item
        let myMenue = NSMenu(title: "MyMenue")
        let item1 = NSMenuItem(title: "我的设置", action: #selector(clickItems1(Sender:)), keyEquivalent: "")
        //添加z到我的菜单
//        myMenue.addItem(item1)
       
        //将我们的菜单项添加到主菜单
        let mFirstItem = menu?.items.first
        //这样添加会覆盖,就是重新生成一个新菜单
//        mFirstItem?.submenu = myMenue
        mFirstItem?.submenu?.insertItem(item1, at: 0)
    }
    
    
   
    
}
extension ThreeVc{

@objc func clickItems1(Sender:NSMenuItem) -> Void {
    print("\(Sender.title)")
}
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值