ãã®ã¬ã€ãã§ã¯ãæåãªäººããã®åŒçšããããã¢ãããŠã£ã³ããŠã«è¡šç€ºããã¢ããªã±ãŒã·ã§ã³ãäœæããŸãã ãã®ã¢ããªã±ãŒã·ã§ã³ãäœæããéçšã§ã次ã®ããšãåŠã³ãŸãã
- ã¡ãã¥ãŒããŒã§ã¢ããªã±ãŒã·ã§ã³ã¢ã€ã³ã³ãå²ãåœãŠãŸã
- ã¢ããªã±ãŒã·ã§ã³ãã¡ãã¥ãŒããŒã§ã®ã¿ãã¹ããã
- ã«ã¹ã¿ã ã¡ãã¥ãŒãè¿œå
- ã€ãã³ãã¢ãã¿ãªã³ã°ã䜿çšããŠããŠãŒã¶ãŒã®èŠæ±æã«ãããã¢ãããŠã£ã³ããŠã衚瀺ããå¿ èŠã«å¿ããŠé衚瀺ã«ããŸã
泚ïŒãã®ã¬ã€ãã¯ãSwiftãšmacOSã«ç²ŸéããŠããããšãåæãšããŠããŸãã
ã¯ããã«
Xcodeãèµ·åããŸãã 次ã«ã ãã¡ã€ã«/æ°èŠ/ãããžã§ã¯ã...ã¡ãã¥ãŒã§ã macOS /ã¢ããªã±ãŒã·ã§ã³/ Cocoa Appãã³ãã¬ãŒããéžæãã 次ãžãã¯ãªãã¯ããŸãã
次ã®ç»é¢ã§ã 補ååãšããŠQuotesãšå ¥åãã çµç¹åãšçµç¹èå¥åãéžæããŸãã 次ã«ãã¢ããªã±ãŒã·ã§ã³èšèªãšããŠSwiftãéžæããã[ ã¹ããŒãªãŒããŒãã䜿çš]ãã§ãã¯ããã¯ã¹ããªã³ã«ãªã£ãŠããããšã確èªããŸãã [ ããã¥ã¡ã³ãããŒã¹ã®ã¢ããªã±ãŒã·ã§ã³ã®äœæ] ã[ ã³ã¢ããŒã¿ã®äœ¿çš] ã[ ãŠããããã¹ããå«ãã]ã[UIãã¹ããå«ãã]ãã§ãã¯ããã¯ã¹ããªãã«ããŸã ã
æåŸã«ãããäžåºŠ[ 次㞠]ãã¯ãªãã¯ãããããžã§ã¯ããä¿åããå Žæãæå®ããŠã[ äœæ ]ãã¯ãªãã¯ããŸã ã
æ°ãããããžã§ã¯ããäœæããããã AppDelegate.swiftãéãã次ã®ããããã£ãã¯ã©ã¹ã«è¿œå ããŸãã
let statusItem = NSStatusBar.system.statusItem(withLength:NSStatusItem.squareLength)
ããã§ã¯ãã¡ãã¥ãŒããŒã®ã¹ããŒã¿ã¹ã¢ã€ãã ïŒã¢ããªã±ãŒã·ã§ã³ã¢ã€ã³ã³ïŒã«ããŠãŒã¶ãŒã«è¡šç€ºãããåºå®é·ãäœæããŸãã
次ã«ãæ°ããã¢ããªã±ãŒã·ã§ã³ãåºå¥ã§ããããã«ãã¡ãã¥ãŒããŒã®ãã®æ°ããã¢ã€ãã ã«ç»åãå²ãåœãŠãå¿ èŠããããŸãã
ãããžã§ã¯ãããã²ãŒã¿ã§ãAssets.xcassetsã«ç§»åããåçãã¢ããããŒãããŠãè³ç£ã«ã¿ãã°ã«ãã©ãã°ããŸãã
ç»åãéžæããŠãå±æ§ã€ã³ã¹ãã¯ã¿ãŒãéããŸãã Render Asãªãã·ã§ã³ãTemplate Imageã«å€æŽããŸãã
ç¬èªã®ç»åã䜿çšããå Žåã¯ãç»åãçœé»ã§ããããšã確èªãã ãã³ãã¬ãŒãã¡ãã¥ãŒãšããŠèšå®ããŠãæãã¡ãã¥ãŒããŒãšæããã¡ãã¥ãŒããŒã®äž¡æ¹ã§ã¢ã€ã³ã³ããããã«èŠããããã«ããŸãã
AppDelegate.swiftã«æ»ãã次ã®ã³ãŒããapplicationDidFinishLaunchingïŒ_ :)ã«è¿œå ããŸã
if let button = statusItem.button { button.image = NSImage(named:NSImage.Name("StatusBarButtonImage")) button.action = #selector(printQuote(_:)) }
ããã§ãã¢ããªã±ãŒã·ã§ã³ã¢ã€ã³ã³ã«è¿œå ããã°ããã®ã¢ããªã±ãŒã·ã§ã³ã¢ã€ã³ã³ãå²ãåœãŠãã¯ãªãã¯ãããšãã«ã¢ã¯ã·ã§ã³ãå²ãåœãŠãŸãã
次ã®ã¡ãœãããã¯ã©ã¹ã«è¿œå ããŸãã
@objc func printQuote(_ sender: Any?) { let quoteText = "Never put off until tomorrow what you can do the day after tomorrow." let quoteAuthor = "Mark Twain" print("\(quoteText) â \(quoteAuthor)") }
ãã®ã¡ãœããã¯ãåã«åŒçšãã³ã³ãœãŒã«ã«åºåããŸãã
objcã¡ãœãããã£ã¬ã¯ãã£ãã«æ³šæããŠãã ããã ããã«ããããã¿ã³ã¯ãªãã¯ãžã®å¿çãšããŠãã®ã¡ââãœããã䜿çšã§ããŸãã
ã¢ããªã±ãŒã·ã§ã³ããã«ãããŠå®è¡ãããšãã¡ãã¥ãŒããŒã«æ°ããã¢ããªã±ãŒã·ã§ã³ã衚瀺ãããŸãã ãã£ãïŒ
ã¡ãã¥ãŒããŒã®ã¢ã€ã³ã³ãã¯ãªãã¯ãããã³ã«ãããŒã¯ããŠã§ã€ã³ã®æåãªæ ŒèšãXcodeã³ã³ãœãŒã«ã«è¡šç€ºãããŸãã
ã¡ã€ã³ãŠã£ã³ããŠãšããã¯ã®ã¢ã€ã³ã³ãé衚瀺ã«ããŸã
æ©èœãçŽæ¥æ±ãåã«è¡ãå¿ èŠã®ããå°ããªããšãããã€ããããŸãã
- ããã¯ã¢ã€ã³ã³ãåé€
- äžèŠãªã¢ããªã±ãŒã·ã§ã³ã®ã¡ã€ã³ãŠã£ã³ããŠãåé€ãã
ããã¯ã¢ã€ã³ã³ãåé€ããã«ã¯ã Info.plistãéããŸã ã æ°ããApplication is agentïŒUIElementïŒããŒãè¿œå ãããã®å€ãYESã«èšå®ããŸãã
ããã§ãã¡ã€ã³ã¢ããªã±ãŒã·ã§ã³ãŠã£ã³ããŠãåŠçããŸãã
- Main.storyboardãéã
- Window Controllerã·ãŒã³ãéžæããŠåé€ããŸã
- ãã¥ãŒã³ã³ãããŒã©ãŒã·ãŒã³ã®äŒæãããã«äœ¿çšããŸã
ã¢ããªã±ãŒã·ã§ã³ããã«ãããŠå®è¡ããŸãã ããã§ãã¢ããªã±ãŒã·ã§ã³ã®ã¡ã€ã³ãŠã£ã³ããŠãšäžèŠãªã¢ã€ã³ã³ã®äž¡æ¹ãããã¯ã«ãããŸããã ãããïŒ
ã¹ããŒã¿ã¹ã¢ã€ãã ã«ã¡ãã¥ãŒãè¿œå
é倧ãªã¢ããªã±ãŒã·ã§ã³ã«ã¯ãã·ã³ã°ã«ã¯ãªãã¯å¿çã ãã§ã¯æããã«äžååã§ãã æ©èœãè¿œå ããæãç°¡åãªæ¹æ³ã¯ãã¡ãã¥ãŒãè¿œå ããããšã§ãã AppDelegateã®æåŸã«ãã®é¢æ°ãè¿œå ããŸãã
func constructMenu() { let menu = NSMenu() menu.addItem(NSMenuItem(title: "Print Quote", action: #selector(AppDelegate.printQuote(_:)), keyEquivalent: "P")) menu.addItem(NSMenuItem.separator()) menu.addItem(NSMenuItem(title: "Quit Quotes", action: #selector(NSApplication.terminate(_:)), keyEquivalent: "q")) statusItem.menu = menu }
ãããŠã applicationDidFinishLaunchingïŒ_ :)ã®æåŸã«ãã®åŒã³åºããè¿œå ããŸã
constructMenu()
NSMenuãäœæãã NSMenuItemã® 3ã€ã®ã€ã³ã¹ã¿ã³ã¹ãããã«è¿œå ãããã®ã¡ãã¥ãŒãã¢ããªã±ãŒã·ã§ã³ã¢ã€ã³ã³ã¡ãã¥ãŒãšããŠèšå®ããŸãã
ããã€ãã®éèŠãªãã€ã³ãïŒ
- ã¡ãã¥ãŒé ç®ã®ã¿ã€ãã«ã¯ãã¡ãã¥ãŒã«è¡šç€ºãããããã¹ãã§ãã ã¢ããªã±ãŒã·ã§ã³ãããŒã«ã©ã€ãºããã®ã«é©ããå ŽæïŒå¿ èŠãªå ŽåïŒã
- action ã¯ããã¿ã³ãŸãã¯ä»ã®ã³ã³ãããŒã«ã®ã¢ã¯ã·ã§ã³ãšåæ§ã«ããŠãŒã¶ãŒãã¡ãã¥ãŒé ç®ãã¯ãªãã¯ãããšãã«åŒã³åºãããã¡ãœããã§ã
- keyEquivalentã¯ãã¡ãã¥ãŒé ç®ãéžæããããã«äœ¿çšã§ããããŒããŒãã·ã§ãŒãã«ããã§ãã å°æåã¯ä¿®é£ŸåãšããŠCmdã䜿çšããå°æåã¯Cmd + Shiftã䜿çšããŸã ã ããã¯ãã¢ããªã±ãŒã·ã§ã³ãæäžäœã«ãããã¢ã¯ãã£ããªå Žåã«ã®ã¿æ©èœããŸãã ãã®å Žåãã¢ããªã±ãŒã·ã§ã³ã«ã¯ããã¯ã«ã¢ã€ã³ã³ããªããããã¡ãã¥ãŒãŸãã¯ä»ã®ãŠã£ã³ããŠã衚瀺ãããŠããå¿ èŠããããŸã
- separatorItemã¯ãä»ã®èŠçŽ ã®éã®ç°è²ã®ç·ã®åœ¢ã®éã¢ã¯ãã£ããªã¡ãã¥ãŒé ç®ã§ãã ã°ã«ãŒãã«äœ¿çšãã
- printQuoteã¯AppDelegateã§æ¢ã«å®çŸ©ããã¡ãœããã§ããã terminateã¯NSApplicationã§å®çŸ©ãããã¡ãœããã§ãã
ã¢ããªã±ãŒã·ã§ã³ãèµ·åãããšãã¢ããªã±ãŒã·ã§ã³ã¢ã€ã³ã³ãã¯ãªãã¯ããŠã¡ãã¥ãŒã衚瀺ãããŸãã
ã¡ãã¥ãŒãã¯ãªãã¯ããŠã¿ãŠãã ãã- èŠç©ã®å°å·ãéžæãããšãXcodeã³ã³ãœãŒã«ã«èŠç©ã衚瀺ãããèŠç©ãçµäºãããšã¢ããªã±ãŒã·ã§ã³ãçµäºããŸãã
ãããã¢ãããè¿œå ãã
ã³ãŒãããã¡ãã¥ãŒãè¿œå ããã®ãã©ãã»ã©ç°¡åããèŠãŸããããXcodeã³ã³ãœãŒã«ã«åŒçšç¬Šã衚瀺ããããšã¯ããŠãŒã¶ãŒãã¢ããªã±ãŒã·ã§ã³ã«æåŸ ãããã®ãšã¯æããã«ç°ãªããŸãã 次ã«ãã·ã³ãã«ãªView Controllerãè¿œå ããŠãæ£ããæ¹æ³ã§èŠç©ããã衚瀺ããŸãã
ãã¡ã€ã«/æ°èŠ/ãã¡ã€ã«...ã¡ãã¥ãŒã«ç§»åãã macOS /ãœãŒã¹/ Cocoa Classãã³ãã¬ãŒããéžæããŠã 次ãžãã¯ãªãã¯ããŸãã
- ã¯ã©ã¹ã«QuotesViewControllerãšããååãä»ããŸã
- NSViewControllerã®çžç¶äººãäœããŸã
- [ ãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã®XIBãã¡ã€ã«ãäœæãã]ãã§ãã¯ããã¯ã¹ããªãã«ãªã£ãŠããããšã確èªããŸãã
- èšèªãSwiftã«èšå®ããŸã
æåŸã«ãããäžåºŠ[ 次㞠]ãã¯ãªãã¯ãããã¡ã€ã«ãä¿åããå ŽæãéžæããŠã[ äœæ ]ãã¯ãªãã¯ããŸã ã
Main.storyboardãéããŸã ã [ View Controller Scene]ãå±éã ã[ View Controller instance]ãéžæããŸã ã
æåã«Identity Inspectorãéžæããã¯ã©ã¹ãQuotesViewControllerã«å€æŽããŠããã ã¹ããŒãªãŒããŒãIDãQuotesViewControllerã«èšå®ããŸã
次ã«ã QuotesViewController.swiftãã¡ã€ã«ã®æåŸã«æ¬¡ã®ã³ãŒããè¿œå ããŸãã
extension QuotesViewController { // MARK: Storyboard instantiation static func freshController() -> QuotesViewController { //1. let storyboard = NSStoryboard(name: NSStoryboard.Name("Main"), bundle: nil) //2. let identifier = NSStoryboard.SceneIdentifier("QuotesViewController") //3. guard let viewcontroller = storyboard.instantiateController(withIdentifier: identifier) as? QuotesViewController else { fatalError("Why cant i find QuotesViewController? - Check Main.storyboard") } return viewcontroller } }
ããã§äœãèµ·ãã£ãŠããŸããïŒ
- Main.storyboardãžã®ãªã³ã¯ãååŸããŸãã
- çŽåã«ã€ã³ã¹ããŒã«ãããã®ãšäžèŽããã·ãŒã³èå¥åãäœæããŸãã
- QuotesViewControllerã®ã€ã³ã¹ã¿ã³ã¹ãäœæããŠè¿ããŸãã
ãã®ã¡ãœãããäœæããã®ã§ã QuotesViewControllerã䜿çšãããã¹ãŠã®äººããã®äœææ¹æ³ãç¥ãå¿ èŠããªããªããŸããã ããã ãã§åäœããŸãã
guardã¹ããŒãã¡ã³ãå ã®fatalErrorã«æ³šæããŠãã ããã éçºäžã«äœãåé¡ãçºçããå Žåã«ãããªãèªèº«ãšéçºããŒã ã®ä»ã®ã¡ã³ããŒãç¥ãããšãã§ããããã«ãããã䜿çšãããassertionFailureããã®ã¯è¯ãããšã§ãã
AppDelegate.swiftã«æ»ããŸãã æ°ããããããã£ãè¿œå ããŸãã
let popover = NSPopover()
次ã«ã pplicationDidFinishLaunchingïŒ_ :)ã次ã®ã³ãŒãã«çœ®ãæããŸãã
func applicationDidFinishLaunching(_ aNotification: Notification) { if let button = statusItem.button { button.image = NSImage(named:NSImage.Name("StatusBarButtonImage")) button.action = #selector(togglePopover(_:)) } popover.contentViewController = QuotesViewController.freshController() }
ã¯ãªãã¯ã¢ã¯ã·ã§ã³ãå€æŽããŠã togglePopoverïŒ_ :)ã¡ãœãããåŒã³åºããŸãããããã«ã€ããŠã¯ãåŸã§èª¬æããŸãã ãŸããã¡ãã¥ãŒãã«ã¹ã¿ãã€ãºããŠè¿œå ãã代ããã«ã QuotesViewControllerããäœãã衚瀺ãããããã¢ãããŠã£ã³ããŠãæ§æããŸãã ã
次ã®3ã€ã®ã¡ãœãããAppDelegateã«è¿œå ããŸãã
@objc func togglePopover(_ sender: Any?) { if popover.isShown { closePopover(sender: sender) } else { showPopover(sender: sender) } } func showPopover(sender: Any?) { if let button = statusItem.button { popover.show(relativeTo: button.bounds, of: button, preferredEdge: NSRectEdge.minY) } } func closePopover(sender: Any?) { popover.performClose(sender) }
showPopoverïŒïŒã¯ãããã¢ããã衚瀺ããŸãã ããªãã¯ãããã©ãããæ¥ããã瀺ãã ãã§ãmacOSã¯ãããé 眮ããã¡ãã¥ãŒããŒããçŸãããã®ããã«ç¢å°ãæããŸãã
closePopoverïŒïŒã¯åã«ãããã¢ãããéãã togglePopoverïŒïŒã¯ç¶æ ã«å¿ããŠãããã¢ããã衚瀺ãŸãã¯é衚瀺ã«ããã¡ãœããã§ãã
ã¢ããªã±ãŒã·ã§ã³ãèµ·åãããã®ã¢ã€ã³ã³ãã¯ãªãã¯ããŸãã
ãã¹ãŠã¯åé¡ãããŸããããã³ã³ãã³ãã¯ã©ãã«ãããŸããïŒ
Quote View Controllerãå®è£ ããŸã
ãŸããåŒçšç¬Šãšå±æ§ãä¿åããããã®ã¢ãã«ãå¿ èŠã§ãã ãã¡ã€ã«/æ°èŠ/ãã¡ã€ã«...ã¡ãã¥ãŒã«ç§»åãã macOS /ãœãŒã¹/ Swiftãã¡ã€ã«ãã³ãã¬ãŒããéžæãã 次ãžãéžæããŸãã ãã¡ã€ã«ã«Quoteãšããååãä»ããŠã[ äœæ ]ãã¯ãªãã¯ããŸã ã
Quote.swiftãã¡ã€ã«ãéãã次ã®ã³ãŒããè¿œå ããŸãã
struct Quote { let text: String let author: String static let all: [Quote] = [ Quote(text: "Never put off until tomorrow what you can do the day after tomorrow.", author: "Mark Twain"), Quote(text: "Efficiency is doing better what is already being done.", author: "Peter Drucker"), Quote(text: "To infinity and beyond!", author: "Buzz Lightyear"), Quote(text: "May the Force be with you.", author: "Han Solo"), Quote(text: "Simplicity is the ultimate sophistication", author: "Leonardo da Vinci"), Quote(text: "It's not just what it looks like and feels like. Design is how it works.", author: "Steve Jobs") ] } extension Quote: CustomStringConvertible { var description: String { return "\"\(text)\" â \(author)" } }
ããã§ã¯ãåçŽãªåŒçšæ§é ãšããã¹ãŠã®åŒçšãè¿ãéçããããã£ãå®çŸ©ããŸãã CustomStringConvertibleãããã³ã«ã«æºæ ããQuoteãäœæããããã䟿å©ãªãã©ãŒãããã®ããã¹ããç°¡åã«ååŸã§ããŸãã
é²æ©ã¯ãããŸãããããããã¹ãŠè¡šç€ºããã«ã¯ã³ã³ãããŒã«ãå¿ èŠã§ãã
ã€ã³ã¿ãŒãã§ã€ã¹èŠçŽ ãè¿œå ãã
Main.storyboardãéããView Controllerã§3ã€ã®ãã¿ã³ïŒ ããã·ã¥ãã¿ã³ ïŒãšã©ãã«ïŒ ãã«ãã©ã€ã³ã©ãã«ïŒãåŒãåºããŸãã
ãã¿ã³ãšã©ãã«ã次ã®ããã«é 眮ããŸãã
20ã®ã®ã£ãããšåçŽæ¹åã®äžå€®ã«å·Šãã¿ã³ã巊端ã«åãä»ããŸãã
20ã®ã®ã£ããã§åçŽã«äžå€®ã«å³ãã¿ã³ãå³ç«¯ã«åãä»ããŸãã
20ã®ã®ã£ããã§æ°Žå¹³æ¹åã®äžå€®ã«äžéšãã¿ã³ãäžç«¯ã«åãä»ããŸãã
ã©ãã«ã®å·Šç«¯ãšå³ç«¯ã20ã®ééã§ãã¿ã³ã«åãä»ããåçŽæ¹åã®äžå€®ã«é 眮ããŸãã
èªåã¬ã€ã¢ãŠããç解ããã®ã«ååãªæ å ±ããªããããããã€ãã®ã¬ã€ã¢ãŠããšã©ãŒã衚瀺ãããŸãã
ã©ãã«ã®ãµã€ãºãå€æŽã§ããããã«ã æ°Žå¹³ã³ã³ãã³ãã®ãã°ã®åªå 床ã249ã«èšå®ããŸãã
次ã®æé ãå®è¡ããŸãã
- å·Šãã¿ã³ã®ç»åãNSGoLeftTemplateã«èšå®ãã ã¿ã€ãã«ãã¯ãªã¢ããŸã
- å³ãã¿ã³ã®ç»åãNSGoRightTemplateã«èšå®ãã ã¿ã€ãã«ãã¯ãªã¢ããŸã
- Quit Quotesã§äžã®ãã¿ã³ã®ã¿ã€ãã«ãèšå®ããŸãã
- ã©ãã«ã®ããã¹ãã®é 眮ãäžå€®ã«èšå®ããŸã ã
- ã©ãã«ã®æ¹è¡ãã¯ãŒãã©ããã«èšå®ãããŠããããšã確èªããŸã ã
QuotesViewController.swiftãéãã QuotesViewControllerã¯ã©ã¹ã®å®è£ ã«æ¬¡ã®ã³ãŒããè¿œå ããŸãã
@IBOutlet var textLabel: NSTextField!
ãã®æ¡åŒµæ©èœãã¯ã©ã¹å®è£ ã«è¿œå ããŸãã QuotesViewController.swiftã«ã¯ã 2ã€ã®ã¯ã©ã¹æ¡åŒµããããŸãã
// MARK: Actions extension QuotesViewController { @IBAction func previous(_ sender: NSButton) { } @IBAction func next(_ sender: NSButton) { } @IBAction func quit(_ sender: NSButton) { } }
åŒçšç¬Šã®è¡šç€ºã«äœ¿çšããã©ãã«ã®ã¢ãŠãã¬ãããšããã¿ã³ã«æ¥ç¶ãã3ã€ã®ã¹ã¿ãã¡ãœãããè¿œå ããŸããã
Interface Builderã§ã³ãŒããæ¥ç¶ãã
泚ïŒXcodeã¯ãã³ãŒãã®å·ŠåŽã ã€ãŸãIBActionããã³IBOutletããŒã¯ãŒãã®é£ã«åãé 眮ããŠããŸãã
ãããã䜿çšããŠãã³ãŒããUIã«æ¥ç¶ããŸãã
AltããŒãæŒããªããã ãããžã§ã¯ãããã²ãŒã¿ãŒã® Main.storyboardãã¯ãªãã¯ããŸãã ãããã£ãŠã ã¹ããŒãªãŒããŒãã¯å³åŽã®ã¢ã·ã¹ã¿ã³ããšãã£ã¿ãŒã§éããã³ãŒãã¯å·ŠåŽã«éããŸãã
textLabelã®å·Šã«ããåãã ã€ã³ã¿ãŒãã§ã€ã¹ãã«ããŒã®ã©ãã«ã«ãã©ãã°ããŸã ã åæ§ã«ã previous ã nextã quitã¡ãœãããããããå·Šãå³ãäžã®ãã¿ã³ãšçµã¿åãããŸãã
ã¢ããªã±ãŒã·ã§ã³ãèµ·åããŸãã
ããã©ã«ãã®ãããã¢ãããµã€ãºã䜿çšããŸããã 倧ãããããã¢ãããŸãã¯å°ãããããã¢ãããå¿ èŠãªå Žåã¯ã ã¹ããŒãªãŒããŒãã§ãµã€ãºãå€æŽããŠãã ããã
ãã¿ã³ã®ã³ãŒããæžã
ã¢ã·ã¹ã¿ã³ããšãã£ã¿ãŒããŸã é衚瀺ã«ããŠããªãå Žåã¯ã[ Cmd-Return ]ãŸãã¯[ ãã¥ãŒ]> [æšæºãšãã£ã¿ãŒ]> [æšæºãšãã£ã¿ãŒã衚瀺 ]ãã¯ãªãã¯ããŸã
QuotesViewController.swiftãéãã次ã®ããããã£ãã¯ã©ã¹å®è£ ã«è¿œå ããŸãã
let quotes = Quote.all var currentQuoteIndex: Int = 0 { didSet { updateQuote() } }
quotesããããã£ã«ã¯ãã¹ãŠã®åŒçšç¬Šãå«ãŸãã currentQuoteIndexã¯çŸåšè¡šç€ºãããŠããåŒçšç¬Šã®ã€ã³ããã¯ã¹ã§ãã CurrentQuoteIndexã«ã¯ãã€ã³ããã¯ã¹ãå€æŽããããšãã«ã©ãã«ã®å 容ãæ°ããåŒçšã§æŽæ°ããããããã£ãªãã¶ãŒããŒããããŸãã
次ã®ã¡ãœãããè¿œå ããŸãã
override func viewDidLoad() { super.viewDidLoad() currentQuoteIndex = 0 } func updateQuote() { textLabel.stringValue = String(describing: quotes[currentQuoteIndex]) }
ãã¥ãŒãèªã¿èŸŒãŸãããšãåŒçšã€ã³ããã¯ã¹ã0ã«èšå®ããŸããããã«ãããã€ã³ã¿ãŒãã§ãŒã¹ãæŽæ°ãããŸãã updateQuoteïŒïŒã¯ãããã¹ãã©ãã«ãæŽæ°ããŠåŒçšã衚瀺ããã ãã§ãã currentQuoteIndexã«å¯Ÿå¿ããŸã ã
æåŸã«ããããã®ã¡ãœããã次ã®ã³ãŒãã§æŽæ°ããŸãã
@IBAction func previous(_ sender: NSButton) { currentQuoteIndex = (currentQuoteIndex - 1 + quotes.count) % quotes.count } @IBAction func next(_ sender: NSButton) { currentQuoteIndex = (currentQuoteIndex + 1) % quotes.count } @IBAction func quit(_ sender: NSButton) { NSApplication.shared.terminate(sender) }
nextïŒïŒããã³previousïŒïŒã¡ãœããã¯ããã¹ãŠã®åŒçšã埪ç°ããŸãã quitã¯ãã¢ããªã±ãŒã·ã§ã³ãéããŸãã
ã¢ããªã±ãŒã·ã§ã³ãèµ·åããŸãã
ã€ãã³ãç£èŠ
ãŠãŒã¶ãŒãã¢ããªã±ãŒã·ã§ã³ã«æåŸ ãããã1ã€ã®ããšããããŸãããŠãŒã¶ãŒããããã¢ãããŠã£ã³ããŠã®å€åŽãã¯ãªãã¯ãããšãããã¢ãããŠã£ã³ããŠãé衚瀺ã«ããããšã§ãã ãããè¡ãã«ã¯ã macOS global event monitorãšåŒã°ããã¡ã«ããºã ãå¿ èŠã§ãã
æ°ããSwiftãã¡ã€ã«ãäœæãããããEventMonitorãšåŒã³ ããã®å 容ã次ã®ã³ãŒãã«çœ®ãæããŸãã
import Cocoa public class EventMonitor { private var monitor: Any? private let mask: NSEvent.EventTypeMask private let handler: (NSEvent?) -> Void public init(mask: NSEvent.EventTypeMask, handler: @escaping (NSEvent?) -> Void) { self.mask = mask self.handler = handler } deinit { stop() } public func start() { monitor = NSEvent.addGlobalMonitorForEvents(matching: mask, handler: handler) } public func stop() { if monitor != nil { NSEvent.removeMonitor(monitor!) monitor = nil } } }
ãã®ã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ãåæåãããšãã«ããªãã¹ã³ããã€ãã³ããã¹ã¯ïŒããŒã¹ãããŒã¯ãããŠã¹ãã€ãŒã«ã®ã¹ã¯ããŒã«ãªã©ïŒãšã€ãã³ããã³ãã©ãŒãæž¡ããŸãã
ãªã¹ãã³ã°ãéå§ããæºåãã§ãããã startïŒïŒãaddGlobalMonitorForEventsMatchingMaskïŒ_ïŒhandler :)ãåŒã³åºããä¿åããŠãããªããžã§ã¯ããè¿ããŸãã ãã¹ã¯ã«å«ãŸããã€ãã³ããçºçãããšããã«ãã·ã¹ãã ã¯ãã³ãã©ãŒãåŒã³åºããŸãã
ã€ãã³ãã®ç£èŠãåæ¢ããã«ã¯ã stopïŒïŒã§removeMonitor ïŒïŒãåŒã³åºãããnilã«èšå®ããŠãªããžã§ã¯ããåé€ããŸãã
æ®ã£ãŠããã®ã¯ãé©åãªã¿ã€ãã³ã°ã§startïŒïŒãšstopïŒïŒãåŒã³åºãããšã§ãã ãŸããã¯ã©ã¹ã¯ãã¯ãªãŒã³ã¢ããããããã«ãã€ãã·ã£ã©ã€ã¶ãŒã§stopïŒïŒãåŒã³åºããŸãã
ã€ãã³ãã¢ãã¿ãŒã®æ¥ç¶
æåŸã«AppDelegate.swiftãéããæ°ããããããã£ãè¿œå ããŸãã
var eventMonitor: EventMonitor?
次ã«ããã®ã³ãŒããè¿œå ããŠã applicationDidFinishLaunchingã®æåŸã«ã€ãã³ãã¢ãã¿ãŒãæ§æããŸãïŒ_ :)
eventMonitor = EventMonitor(mask: [.leftMouseDown, .rightMouseDown]) { [weak self] event in if let strongSelf = self, strongSelf.popover.isShown { strongSelf.closePopover(sender: event) } }
å·ŠãŸãã¯å³ã®ãã¿ã³ãã¯ãªãã¯ãããšãã¢ããªã±ãŒã·ã§ã³ã«éç¥ãããŸãã 泚ïŒã¢ããªã±ãŒã·ã§ã³å ã§ã®ããŠã¹ã¯ãªãã¯ã«å¿çããŠãã³ãã©ãŒã¯åŒã³åºãããŸããã ãããããããã¢ãããã¯ãªãã¯ããŠãéããªãçç±ã§ãã
AppDelegateãšEventMonitoréã®åŒ·åãªãªã³ã¯ã«ãŒãã®å±éºãåé¿ããããã«ã 匱ã èªå·±åç §ã䜿çšããŸãã
showPopoverïŒ_ :)ã¡ãœããã®æåŸã«æ¬¡ã®ã³ãŒããè¿œå ããŸãã
eventMonitor?.start()
ããã§ã¯ããããã¢ãããŠã£ã³ããŠã衚瀺ããããšãã«ã€ãã³ãã®ç£èŠãéå§ããŸãã
次ã«ã closePopoverïŒ_ :)ã¡ãœããã®æåŸã«ã³ãŒããè¿œå ããŸãã
eventMonitor?.stop()
ããã§ããããã¢ãããéãããç£èŠãçµäºããŸãã
ã¢ããªã±ãŒã·ã§ã³ã®æºåãã§ããŸããïŒ
ãããã«
ããã« ããã®ãããžã§ã¯ãã®å®å šãªã³ãŒãããããŸãã
ã¡ãã¥ãŒããŒã«ããã¢ããªã±ãŒã·ã§ã³ã§ã¡ãã¥ãŒãšãããã¢ãããèšå®ããæ¹æ³ãåŠç¿ããŸããã è€æ°ã®ã¿ã°ãŸãã¯ãã©ãŒããããããããã¹ããè©ŠããŠãåŒçšç¬ŠãããããèŠãŠã¿ãŸãããïŒ ãŸãã¯ãããã¯ãšã³ããæ¥ç¶ããŠã€ã³ã¿ãŒãããããèŠç©ãããåãåããŸããïŒ ãŸãã¯ãããŒããŒãã䜿çšããŠåŒçšç¬Šéã移åããŸããïŒ
ç 究ããã®ã«é©ããå Žæã¯ãå ¬åŒã®ããã¥ã¡ã³ãNSMenu ã NSPopoverããã³NSStatusItemã§ãã