本文共 16739 字,大约阅读时间需要 55 分钟。
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函数入口 */@NSApplicationMainclass 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) { print("选中操作 ") } //取消选中操作 func collectionView(_ collectionView: NSCollectionView, didDeselectItemsAt indexPaths: Set ) { print("取消选中") } }
5 NSAlert 和 NSPopover 提示的使用
import Cocoaclass 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")// } } }//NSAlertDelegateextension TwoVc:NSAlertDelegate{ //return false 表示代理自己处理,否则就是系统自己处理 func alertShowHelp(_ alert: NSAlert) -> Bool { //一般跳转帮助页面来提示 print("点击了帮组选项") return false }}//NSPopoverDelegateextension 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)")}}
转载地址:http://benvb.baihongyu.com/