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