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)")
}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章