рдореЗрдиреВ рдмрд╛рд░ рдкрд░ рд╕реНрдерд┐рдд рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд▓рдВрдмреЗ рд╕рдордп рд╕реЗ macOS рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдЬрд╛рдиреЗ рдЬрд╛рддреЗ рд╣реИрдВред рдЗрдирдореЗрдВ рд╕реЗ рдХреБрдЫ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдореЗрдВ рдПрдХ "рд╕рд╛рдорд╛рдиреНрдп" рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ, рдЕрдиреНрдп рдХреЗрд╡рд▓ рдореЗрдиреВ рдмрд╛рд░ рдореЗрдВ рд╕реНрдерд┐рдд рд╣реИрдВред
рдЗрд╕ рдЧрд╛рдЗрдб рдореЗрдВ, рдЖрдк рдПрдХ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд▓рд┐рдЦреЗрдВрдЧреЗ рдЬреЛ рдкреЙрдк-рдЕрдк рд╡рд┐рдВрдбреЛ рдореЗрдВ рдкреНрд░рд╕рд┐рджреНрдз рд▓реЛрдЧреЛрдВ рдХреЗ рдХрдИ рдЙрджреНрдзрд░рдг рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдмрдирд╛рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ, рдЖрдк рд╕реАрдЦреЗрдВрдЧреЗ:
- рдореЗрдиреВ рдмрд╛рд░ рдореЗрдВ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЖрдЗрдХрди рдЕрд╕рд╛рдЗрди рдХрд░реЗрдВ
- рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдХреЗрд╡рд▓ рдореЗрдиреВ рдмрд╛рд░ рдкрд░ рд╣реЛрд╕реНрдЯ рдХрд░реЗрдВ
- рдХрд╕реНрдЯрдо рдореЗрдиреВ рдЬреЛрдбрд╝реЗрдВ
- рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдЕрдиреБрд░реЛрдз рдкрд░ рдкреЙрдк-рдЕрдк рд╡рд┐рдВрдбреЛ рджрд┐рдЦрд╛рдПрдВ рдФрд░ рдИрд╡реЗрдВрдЯ рдореЙрдирд┐рдЯрд░рд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕реЗ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдиреЗ рдкрд░ рдЫрд┐рдкрд╛рдПрдВ
рдиреЛрдЯ: рдпрд╣ рдорд╛рд░реНрдЧрджрд░реНрд╢рд┐рдХрд╛ рдорд╛рдирддреА рд╣реИ рдХрд┐ рдЖрдк рд╕реНрд╡рд┐рдлреНрдЯ рдФрд░ macOS рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рд╣реИрдВред
рд╢реБрд░реБрдЖрдд рд╣реЛ рд░рд╣реА рд╣реИ
Xcode рд▓реЙрдиреНрдЪ рдХрд░реЗрдВред рдЕрдЧрд▓рд╛,
рдлрд╝рд╛рдЗрд▓ / рдирдпрд╛ / рдкреНрд░реЛрдЬреЗрдХреНрдЯ ... рдореЗрдиреВ рдкрд░,
macOS / рдПрдкреНрд▓рд┐рдХреЗрд╢рди / рдХреЛрдХреЛ рдРрдк рдЯреЗрдореНрдкрд▓реЗрдЯ рдЪреБрдиреЗрдВ рдФрд░
рдЕрдЧрд▓рд╛ рдХреНрд▓рд┐рдХ рдХрд░реЗрдВред
рдЕрдЧрд▓реА рд╕реНрдХреНрд░реАрди рдкрд░,
рдЙрддреНрдкрд╛рдж рдирд╛рдо рдХреЗ рд░реВрдк рдореЗрдВ рдЙрджреНрдзрд░рдг рджрд░реНрдЬ рдХрд░реЗрдВ, рдЕрдкрдирд╛
рд╕рдВрдЧрдарди рдирд╛рдо рдФрд░
рд╕рдВрдЧрдарди рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдЪреБрдиреЗрдВ ред рдлрд┐рд░ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рд╕реНрд╡рд┐рдлреНрдЯ рдХреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рднрд╛рд╖рд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдЪреБрдирд╛ рдЧрдпрд╛ рд╣реИ рдФрд░
рд╕реНрдЯреЛрд░реАрдмреЛрд░реНрдб рдХрд╛
рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ рдЪреЗрдХрдмреЙрдХреНрд╕ рдЪреЗрдХ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
рджрд╕реНрддрд╛рд╡реЗрдЬрд╝-рдЖрдзрд╛рд░рд┐рдд рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдмрдирд╛рдПрдБ ,
рдХреЛрд░ рдбреЗрдЯрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ ,
рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдг рд╢рд╛рдорд┐рд▓ рдХрд░реЗрдВ рдФрд░
UI рдЯреЗрд╕реНрдЯ рдЪреЗрдХрдмреЙрдХреНрд╕ рд╢рд╛рдорд┐рд▓ рдХрд░реЗрдВ ред

рдЕрдВрдд рдореЗрдВ, рдлрд┐рд░ рд╕реЗ рдХреНрд▓рд┐рдХ рдХрд░реЗрдВ, рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЛ рдмрдЪрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдерд╛рди рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реЗрдВ рдФрд░
рдХреНрд░рд┐рдПрдЯ рдкрд░ рдХреНрд▓рд┐рдХ
рдХрд░реЗрдВ ред
рдПрдХ рдмрд╛рд░ рдирдпрд╛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ
рдмрдирдиреЗ рдХреЗ рдмрд╛рдж,
AppDelegate.swift рдЦреЛрд▓реЗрдВ рдФрд░ рдирд┐рдореНрди рд╕рдВрдкрддреНрддрд┐ рдХреЛ рд╡рд░реНрдЧ рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ:
let statusItem = NSStatusBar.system.statusItem(withLength:NSStatusItem.squareLength)
рдпрд╣рд╛рдВ рд╣рдо рдореЗрдиреВ рдмрд╛рд░ рд╕реНрдЯреЗрдЯрд╕ рдЖрдЗрдЯрдо (рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЖрдЗрдХрди) рдореЗрдВ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд▓рдВрдмрд╛рдИ рдмрдирд╛рддреЗ рд╣реИрдВ рдЬреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛ред
рдлрд┐рд░ рд╣рдореЗрдВ рдореЗрдиреВ рдмрд╛рд░ рдореЗрдВ рдЗрд╕ рдирдП рдЖрдЗрдЯрдо рдкрд░ рдЕрдкрдиреА рддрд╕реНрд╡реАрд░ рдЕрд╕рд╛рдЗрди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рддрд╛рдХрд┐ рд╣рдо рдЕрдкрдиреЗ рдирдП рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдЕрд▓рдЧ рдХрд░ рд╕рдХреЗрдВред
рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдиреЗрд╡рд┐рдЧреЗрдЯрд░ рдореЗрдВ, Assets.xcassets рдкрд░ рдЬрд╛рдПрдВ,
рдПрдХ рддрд╕реНрд╡реАрд░ рдЕрдкрд▓реЛрдб рдХрд░реЗрдВ рдФрд░ рдЗрд╕реЗ рдПрд╕реЗрдЯ рдХреИрдЯрд▓реЙрдЧ рдореЗрдВ рдЦреАрдВрдЪреЗрдВред
рдПрдХ рдЪрд┐рддреНрд░ рдХрд╛ рдЪрдпрди рдХрд░реЗрдВ рдФрд░ рд╡рд┐рд╢реЗрд╖рддрд╛ рдирд┐рд░реАрдХреНрд╖рдХ рдЦреЛрд▓реЗрдВред
рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдореЗрдЬ рдХреЗ рд╡рд┐рдХрд▓реНрдк рдХреЗ
рд░реВрдк рдореЗрдВ
рд░реЗрдВрдбрд░ рдмрджрд▓реЗрдВред

рдпрджрд┐ рдЖрдк рдЕрдкрдиреА рдЦреБрдж рдХреА рдЫрд╡рд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рдЫрд╡рд┐ рдХрд╛рд▓реА рдФрд░ рд╕рдлреЗрдж рд╣реИ рдФрд░ рдЗрд╕реЗ
рдЯреЗрдореНрдкрд▓реЗрдЯ рдЫрд╡рд┐ рдХреЗ рд░реВрдк рдореЗрдВ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░
рдХрд░реЗрдВ рддрд╛рдХрд┐ рдЖрдЗрдХрди рдЕрдВрдзреЗрд░реЗ рдФрд░ рдкреНрд░рдХрд╛рд╢ рдореЗрдиреВ рдмрд╛рд░ рджреЛрдиреЛрдВ рдкрд░ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд▓рдЧреЗред
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 рдЦреЛрд▓реЗрдВред рдирдпрд╛
рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЬреЛрдбрд╝реЗрдВ
рдПрдЬреЗрдВрдЯ (UIElement) рдХреБрдВрдЬреА рд╣реИ рдФрд░ рдЗрд╕рдХрд╛ рдорд╛рди
YES рдкрд░ рд╕реЗрдЯ рдХрд░реЗрдВред

рдЕрдм рдореБрдЦреНрдп рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╡рд┐рдВрдбреЛ рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдХрд╛ рд╕рдордп рд╣реИред
- рдЦреБрд▓рд╛ рдореЗрдирд╕реНрдЯреЛрд░реАрдмреЛрд░реНрдб
- рд╡рд┐рдВрдбреЛ рдХрдВрдЯреНрд░реЛрд▓рд░ рджреГрд╢реНрдп рдХрд╛ рдЪрдпрди рдХрд░реЗрдВ рдФрд░ рдЗрд╕реЗ рд╣рдЯрд╛ рджреЗрдВ
- рдирд┐рдпрдВрддреНрд░рдХ рджреГрд╢реНрдп рдЫреЛрдбрд╝реЗрдВ, рд╣рдо рдЬрд▓реНрдж рд╣реА рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ

рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрдирд╛рдПрдВ рдФрд░ рдЪрд▓рд╛рдПрдВред рдЕрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдореБрдЦреНрдп рд╡рд┐рдВрдбреЛ рдФрд░ рдЧреЛрджреА рдореЗрдВ рдЕрдирд╛рд╡рд╢реНрдпрдХ рдЖрдЗрдХрди рджреЛрдиреЛрдВ рдирд╣реАрдВ рд╣реИрдВред рдмрд╣реБрдд рдмрдврд╝рд┐рдпрд╛!
рд╕реНрдерд┐рддрд┐ рдЖрдЗрдЯрдо рдореЗрдВ рдореЗрдиреВ рдЬреЛрдбрд╝реЗрдВ
рдПрдХ рдХреНрд▓рд┐рдХ рдХреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдПрдХ рдЧрдВрднреАрд░ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИред рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдЬреЛрдбрд╝рдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рддрд░реАрдХрд╛ рдПрдХ рдореЗрдиреВ рдЬреЛрдбрд╝рдирд╛ рд╣реИред рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ
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 рдЙрджрд╛рд╣рд░рдг рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рдФрд░ рдЗрд╕ рдореЗрдиреВ рдХреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЖрдЗрдХрди рдореЗрдиреВ рдХреЗ рд░реВрдк рдореЗрдВ рд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВред
рдХреБрдЫ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд┐рдВрджреБ:
- рдореЗрдиреВ рдЖрдЗрдЯрдо рдХрд╛ рд╢реАрд░реНрд╖рдХ рдкрд╛рда рд╣реИ рдЬреЛ рдореЗрдиреВ рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреЗрддрд╛ рд╣реИред рдЖрд╡реЗрджрди рдХреЛ рд╕реНрдерд╛рдиреАрдп рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдЪреНрдЫреА рдЬрдЧрд╣ (рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ)ред
- рдХреНрд░рд┐рдпрд╛ , рдПрдХ рдмрдЯрди рдпрд╛ рдЕрдиреНрдп рдирд┐рдпрдВрддреНрд░рдг рдХреА рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреА рддрд░рд╣, рдПрдХ рд╡рд┐рдзрд┐ рд╣реИ рдЬрд┐рд╕реЗ рддрдм рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрдм рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдореЗрдиреВ рдЖрдЗрдЯрдо рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рддрд╛ рд╣реИ
- keyEquivalent рдПрдХ рдХреАрдмреЛрд░реНрдб рд╢реЙрд░реНрдЯрдХрдЯ рд╣реИ рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдЖрдк рдореЗрдиреВ рдЖрдЗрдЯрдо рдХрд╛ рдЪрдпрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд▓реЛрдЕрд░рдХреЗрд╕ рд╡рд░реНрдг Cmd рдХреЛ рдПрдХ рд╕рдВрд╢реЛрдзрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рд▓реЛрдЕрд░рдХреЗрд╕ рд╡рд░реНрдг Cmd + Shift рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рдпрд╣ рдХреЗрд╡рд▓ рддрднреА рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдЬрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрд╣реБрдд рдКрдкрд░ рд╣реЛ рдФрд░ рд╕рдХреНрд░рд┐рдп рд╣реЛред рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдХрд┐ рдореЗрдиреВ рдпрд╛ рдХреЛрдИ рдЕрдиреНрдп рд╡рд┐рдВрдбреЛ рджрд┐рдЦрд╛рдИ рджреЗ, рдХреНрдпреЛрдВрдХрд┐ рд╣рдорд╛рд░реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдбреЙрдХ рдореЗрдВ рдПрдХ рдЖрдЗрдХрди рдирд╣реАрдВ рд╣реИ
- рд╕реЗрдкрд░реЗрдЯрд░ рдЗрдЯреЗрдо рдЕрдиреНрдп рддрддреНрд╡реЛрдВ рдХреЗ рдмреАрдЪ рдПрдХ рдЧреНрд░реЗ рд▓рд╛рдЗрди рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рдирд┐рд╖реНрдХреНрд░рд┐рдп рдореЗрдиреВ рдЖрдЗрдЯрдо рд╣реИред рдЗрд╕реЗ рдЧреНрд░реБрдк рдореЗрдВ рдпреВрдЬ рдХрд░реЗрдВ
- PrintQuote рд╡рд╣ рд╡рд┐рдзрд┐ рд╣реИ рдЬрд┐рд╕реЗ рдЖрдкрдиреЗ рдкрд╣рд▓реЗ рд╣реА AppDelegate рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдерд╛, рдФрд░ рд╕рдорд╛рдкреНрдд рдХрд░рдирд╛ NSApplication рджреНрд╡рд╛рд░рд╛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рд╡рд┐рдзрд┐ рд╣реИред
рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд▓реЙрдиреНрдЪ рдХрд░реЗрдВ рдФрд░ рдЖрдкрдХреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЖрдЗрдХрди рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рдХреЗ рдПрдХ рдореЗрдиреВ рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛ред

рдореЗрдиреВ рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВ -
рдкреНрд░рд┐рдВрдЯ рдХреЛрдЯ рдХрд╛ рдЪрдпрди рдПрдХреНрд╕рдХреЛрдб рдХрдВрд╕реЛрд▓ рдореЗрдВ рдмреЛрд▓реА рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ, рдФрд░
рдХреНрд╡рд┐рдЯ рдХреЛрдЯреНрд╕ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рд╕рдорд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИред
рдПрдХ рдкреЙрдкрдЕрдк рдЬреЛрдбрд╝реЗрдВ
рдЖрдкрдиреЗ рджреЗрдЦрд╛ рдХрд┐ рдХреЛрдб рд╕реЗ рдореЗрдиреВ рдЬреЛрдбрд╝рдирд╛ рдХрд┐рддрдирд╛ рдЖрд╕рд╛рди рд╣реИ, рд▓реЗрдХрд┐рди Xcode рдХрдВрд╕реЛрд▓ рдореЗрдВ рдПрдХ рдЙрджреНрдзрд░рдг рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдирд╛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рджреНрд╡рд╛рд░рд╛ рдЖрд╡реЗрджрди рд╕реЗ рдЕрдкреЗрдХреНрд╖рд┐рдд рдирд╣реАрдВ рд╣реИред рдЕрдм рд╣рдо рд╕рд╣реА рддрд░реАрдХреЗ рд╕реЗ рдЙрджреНрдзрд░рдг рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд░рд▓ рджреГрд╢реНрдп рдирд┐рдпрдВрддреНрд░рдХ рдЬреЛрдбрд╝ рджреЗрдВрдЧреЗред
рдлрд╝рд╛рдЗрд▓ / рдирдпрд╛ / рдлрд╝рд╛рдЗрд▓ ... рдореЗрдиреВ рдкрд░ рдЬрд╛рдПрдВ,
macOS / Source / рдХреЛрдХреЛ рдХреНрд▓рд╛рд╕ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЪреБрдиреЗрдВ рдФрд░
Next рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░реЗрдВред

- рд╡рд░реНрдЧ рдХрд╛ рдирд╛рдо QuotesViewController
- NSViewController рдХрд╛ рдПрдХ рд╡рд╛рд░рд┐рд╕ рдмрдирд╛рдПрдВ
- рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рдЪреЗрдХрдмреЙрдХреНрд╕ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рд▓рд┐рдП XIB рдлрд╝рд╛рдЗрд▓ рднреА рдЪреЗрдХ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ
- рднрд╛рд╖рд╛ рдХреЛ рд╕реНрд╡рд┐рдлреНрдЯ рдкрд░ рд╕реЗрдЯ рдХрд░реЗрдВ
рдЕрдВрдд рдореЗрдВ,
рдиреЗрдХреНрд╕реНрдЯ рдкрд░ рдлрд┐рд░ рд╕реЗ рдХреНрд▓рд┐рдХ рдХрд░реЗрдВ, рдлрд╛рдЗрд▓ рд╕реЗрд╡ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд▓реЛрдХреЗрд╢рди рдЪреБрдиреЗрдВ рдФрд░
рдХреНрд░рд┐рдПрдЯ рдкрд░ рдХреНрд▓рд┐рдХ
рдХрд░реЗрдВ ред
рдЕрдм
Main.storyboard рдЦреЛрд▓реЗрдВред
рджреГрд╢реНрдп рдирд┐рдпрдВрддреНрд░рдХ рджреГрд╢реНрдп рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░реЗрдВ рдФрд░
рджреГрд╢реНрдп рдирд┐рдпрдВрддреНрд░рдХ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЪрдпрди рдХрд░реЗрдВред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ
рдЖрдЗрдбреЗрдВрдЯрд┐рдЯреА рдЗрдВрд╕реНрдкреЗрдХреНрдЯрд░ рдХрд╛ рдЪрдпрди рдХрд░реЗрдВ рдФрд░ рдХреНрд▓рд╛рд╕ рдХреЛ
QuotesViewController рдореЗрдВ рдмрджрд▓реЗрдВ , рдлрд┐рд░
рд╕реНрдЯреЛрд░реАрдмреЛрд░реНрдб рдЖрдИрдбреА рдХреЛ
QuotesViewController рдкрд░ рд╕реЗрдЯ рдХрд░реЗрдВ
рдЕрдм
QuotesViewController.swift рдлрд╝рд╛рдЗрд▓ рдХреЗ рдЕрдВрдд рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдЬреЛрдбрд╝реЗрдВ:
extension QuotesViewController {
рдпрд╣рд╛рдБ рдХреНрдпрд╛ рд╣реЛ рд░рд╣рд╛ рд╣реИ:
- рд╣рдореЗрдВ Main.storyboard рдХрд╛ рд▓рд┐рдВрдХ рдорд┐рд▓рддрд╛ рд╣реИред
- рдПрдХ рджреГрд╢реНрдп рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдмрдирд╛рдПрдВ рдЬреЛ рд╣рдорд╛рд░реЗ рджреНрд╡рд╛рд░рд╛ рдЕрднреА-рдЕрднреА рдКрдкрд░ рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдП рдЧрдП рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реЛред
- QuotesViewController рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рдПрдВ рдФрд░ рдЗрд╕реЗ рд╡рд╛рдкрд╕ рдХрд░реЗрдВред
рдЖрдк рдпрд╣ рд╡рд┐рдзрд┐ рдмрдирд╛рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдЕрдм
QuotesViewController рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рд╕рднреА рдХреЛ рдпрд╣ рдЬрд╛рдирдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рд╕рд┐рд░реНрдл рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред
рдЧрд╛рд░реНрдб рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рдХреЗ рдЕрдВрджрд░
рдШрд╛рддрдХ рдиреЛрдЯ рдкрд░ рдзреНрдпрд╛рди рджреЗрдВред рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЕрдЪреНрдЫрд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдпрд╛ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рддрд╛рдХрд┐ рдЕрдЧрд░ рд╡рд┐рдХрд╛рд╕ рдореЗрдВ рдХреБрдЫ рдЧрд▓рдд рд╣реЛ рдЬрд╛рдП, рддреЛ рдЖрдк рд╕реНрд╡рдпрдВ, рдФрд░ рд╡рд┐рдХрд╛рд╕ рдЯреАрдо рдХреЗ рдЕрдиреНрдп рд╕рджрд╕реНрдпреЛрдВ рдХреЛ рдкрддрд╛ рдЪрд▓ рдЬрд╛рдПред
рдЕрдм рд╡рд╛рдкрд╕
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 рд╕реЗ рдХреБрдЫ
рджрд┐рдЦрд╛рдПрдЧрд╛ ред
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 () рдПрдХ рдРрд╕реА рд╡рд┐рдзрд┐ рд╣реИ рдЬреЛ рдпрд╛ рддреЛ рдкреЙрдкрдЕрдк рджрд┐рдЦрд╛рддрд╛ рд╣реИ рдпрд╛ рдЕрдкрдиреЗ рд░рд╛рдЬреНрдп рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИред
рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд▓реЙрдиреНрдЪ рдХрд░реЗрдВ рдФрд░ рдЙрд╕рдХреЗ рдЖрдЗрдХрди рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░реЗрдВред

рд╕рдм рдХреБрдЫ рдареАрдХ рд╣реИ, рд▓реЗрдХрд┐рди рд╕рд╛рдордЧреНрд░реА рдХрд╣рд╛рдВ рд╣реИ?
рд╣рдо рдЙрджреНрдзрд░рдг рджреГрд╢реНрдп рдирд┐рдпрдВрддреНрд░рдХ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ
рдкрд╣рд▓реЗ рдЖрдкрдХреЛ рдЙрджреНрдзрд░рдг рдФрд░ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдореЙрдбрд▓ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред
рдлрд╝рд╛рдЗрд▓ / рдирдИ / рдлрд╝рд╛рдЗрд▓ ... рдореЗрдиреВ рдкрд░ рдЬрд╛рдПрдВ рдФрд░ рдЙрд╕рдХреЗ
рдмрд╛рдж macOS / Source / Swift рдлрд╝рд╛рдЗрд▓ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЪреБрдиреЗрдВ ред рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдирд╛рдо
рдЙрджреНрдзрд░рдг рдФрд░
рдмрдирд╛рдПрдБ рдкрд░ рдХреНрд▓рд┐рдХ
рдХрд░реЗрдВ ред
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 рдХрд╛ рдЕрдиреБрдкрд╛рд▓рди рдХрд┐рдпрд╛, рдЗрд╕рд▓рд┐рдП рд╣рдо рдЖрд╕рд╛рдиреА рд╕реЗ рдЖрд╕рд╛рдиреА рд╕реЗ рд╕реНрд╡рд░реВрдкрд┐рдд рдкрд╛рда рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдкреНрд░рдЧрддрд┐ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдореЗрдВ рдЕрднреА рднреА рдпрд╣ рд╕рдм рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдпрдВрддреНрд░рдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рддрддреНрд╡ рдЬреЛрдбрд╝реЗрдВ
рдУрдкрди рдореЗрди.рд╕реНрдЯреЛрд░реАрдмреЛрд░реНрдб рдФрд░ рд╡реНрдпреВ рдХрдВрдЯреНрд░реЛрд▓рд░ рдкрд░ 3 рдмрдЯрди (
рдкреБрд╢ рдмрдЯрди ) рдФрд░ рд▓реЗрдмрд▓ (рдорд▓реНрдЯреАрд▓рд╛рдЗрди
рд▓реЗрдмрд▓) рдХреЛ рдмрд╛рд╣рд░ рдирд┐рдХрд╛рд▓реЗрдВред
рдмрдЯрди рдФрд░ рд▓реЗрдмрд▓ рд▓рдЧрд╛рдПрдВ рддрд╛рдХрд┐ рд╡реЗ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдВ:

рдмрд╛рдПрдВ рдмрдЯрди рдХреЛ 20 рдЫреЛрд░ рдФрд░ рдХреЗрдВрджреНрд░ рдХреЗ рдЕрдВрддрд░рд╛рд▓ рдХреЗ рд╕рд╛рде рдмрд╛рдПрдВ рдХрд┐рдирд╛рд░реЗ рдкрд░ рд╕рдВрд▓рдЧреНрди рдХрд░реЗрдВред
рджрд╛рдПрдВ рдХрд┐рдирд╛рд░реЗ рдХреЛ 20 рдФрд░ рдХреЗрдВрджреНрд░ рдХреЗ рдЕрдВрддрд░рд╛рд▓ рдХреЗ рд╕рд╛рде рджрд╛рд╣рд┐рдиреЗ рдХрд┐рдирд╛рд░реЗ рдкрд░ рд╕рдВрд▓рдЧреНрди рдХрд░реЗрдВред
рдиреАрдЪреЗ рдХреЗ рдХрд┐рдирд╛рд░реЗ рдХреЛ 20 рдХреЗ рдмреАрдЪ рдФрд░ рдХреНрд╖реИрддрд┐рдЬ рд░реВрдк рд╕реЗ рдХреЗрдВрджреНрд░ рдХреЗ рд╕рд╛рде рдиреАрдЪреЗ рдХреЗ рдмрдЯрди рдХреЛ рд╕рдВрд▓рдЧреНрди рдХрд░реЗрдВред
20 рдХреЗ рдЕрдВрддрд░рд╛рд▓ рдХреЗ рд╕рд╛рде рдмрдЯрди рдХреЗ рдирд┐рд╢рд╛рди рдХреЗ рдмрд╛рдПрдВ рдФрд░ рджрд╛рдПрдВ рдХрд┐рдирд╛рд░реЛрдВ рдХреЛ рд▓рдВрдмрд╡рдд рд░реВрдк рд╕реЗ рд╕рдВрд▓рдЧреНрди рдХрд░реЗрдВред

рдЖрдкрдХреЛ рдХрдИ рд▓реЗрдЖрдЙрдЯ рддреНрд░реБрдЯрд┐рдпрд╛рдВ рджрд┐рдЦрд╛рдИ рджреЗрдВрдЧреА, рдХреНрдпреЛрдВрдХрд┐
рдСрдЯреЛ рд▓реЗрдЖрдЙрдЯ рдХреЗ рд▓рд┐рдП рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдЬрд╛рдирдХрд╛рд░реА рдирд╣реАрдВ рд╣реИред
рд▓реЗрдмрд▓ рдХреЛ рдЖрдХрд╛рд░ рдмрджрд▓рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП 249 рддрдХ
рдХреНрд╖реИрддрд┐рдЬ рд╕рд╛рдордЧреНрд░реА рдЖрд▓рд┐рдВрдЧрди рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдВред

рдЕрдм рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд░реЗрдВ:
- NSGoLeftTemplate рдкрд░ рдмрд╛рдИрдВ рдмрдЯрди рдЫрд╡рд┐ рд╕реЗрдЯ рдХрд░реЗрдВ рдФрд░ рд╢реАрд░реНрд╖рдХ рд╕рд╛рдлрд╝ рдХрд░реЗрдВ
- NSGoRightTemplate рдкрд░ рд╕рд╣реА рдмрдЯрди рдЫрд╡рд┐ рд╕реЗрдЯ рдХрд░реЗрдВ рдФрд░ рд╢реАрд░реНрд╖рдХ рд╕рд╛рдлрд╝ рдХрд░реЗрдВ
- рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рдмрдЯрди рдХрд╛ рд╢реАрд░реНрд╖рдХ рдХреНрд╡рд┐рдЯ рдХреЛрдЯреНрд╕ рдкрд░ рд╕реЗрдЯ рдХрд░реЗрдВред
- рдХреЗрдВрджреНрд░ рдореЗрдВ рд▓реЗрдмрд▓ рдХреЗ рдкрд╛рда рд╕рдВрд░реЗрдЦрдг рд╕реЗрдЯ рдХрд░реЗрдВред
- рдЬрд╛рдБрдЪреЗрдВ рдХрд┐ рд▓реЗрдмрд▓ рдкрд░ рд▓рд╛рдЗрди рдмреНрд░реЗрдХ рд╡рд░реНрдб рд░реИрдк рдкрд░ рд╕реЗрдЯ рд╣реИред
рдЕрдм
QuotesViewController.swift рдЦреЛрд▓реЗрдВ рдФрд░
QuotesViewController рд╡рд░реНрдЧ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП рдирд┐рдореНрди рдХреЛрдб рдЬреЛрдбрд╝реЗрдВ:
@IBOutlet var textLabel: NSTextField!
рдЗрд╕ рд╡рд┐рд╕реНрддрд╛рд░ рдХреЛ рд╡рд░реНрдЧ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдЬреЛрдбрд╝реЗрдВред рдЕрдм
QuotesViewController.swift рдореЗрдВ рджреЛ рдХреНрд▓рд╛рд╕ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд╣реИрдВред
рд╣рдордиреЗ рдХреЗрд╡рд▓ рдЙрд╕ рд▓реЗрдмрд▓ рдХреЗ рд▓рд┐рдП
рдЖрдЙрдЯрд▓реЗрдЯ рдЬреЛрдбрд╝рд╛ рд╣реИ рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣рдо рдЙрджреНрдзрд░рдгреЛрдВ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░реЗрдВрдЧреЗ, рдФрд░ 3 рд╕реНрдЯрдм рд╡рд┐рдзрд┐рдпрд╛рдБ рдЬрд┐рдиреНрд╣реЗрдВ рд╣рдо рдмрдЯрдиреЛрдВ рдХреЗ рд╕рд╛рде рдЬреЛрдбрд╝реЗрдВрдЧреЗред
рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдмрд┐рд▓реНрдбрд░ рдХреЗ рд╕рд╛рде рдХреЛрдб рдХрдиреЗрдХреНрдЯ рдХрд░рдирд╛
рдиреЛрдЯ: Xcode рдиреЗ
IBAction рдФрд░
IBOutlet рдХреАрд╡рд░реНрдбреНрд╕ рдХреЗ рдмрдЧрд▓ рдореЗрдВ - рдЖрдкрдХреЗ рдХреЛрдб рдХреЗ рдмрд╛рдИрдВ рдУрд░ рдордВрдбрд▓рд┐рдпреЛрдВ рдХреЛ рд░рдЦрд╛ рд╣реИред

рд╣рдо рдЙрдиреНрд╣реЗрдВ рдпреВрдЖрдИ рд╕реЗ рдХреЛрдб рдХрдиреЗрдХреНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред
рдкреВрд░реА рдХреБрдВрдЬреА рдХреЛ
рджрдмрд╛рдП рд░рдЦрддреЗ рд╣реБрдП,
рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдиреЗрд╡рд┐рдЧреЗрдЯрд░ рдореЗрдВ
Main.storyboard рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░реЗрдВред рдЗрд╕ рдкреНрд░рдХрд╛рд░,
рд╕реНрдЯреЛрд░реАрдмреЛрд░реНрдб рджрд╛рдИрдВ рдУрд░
рд╕рд╣рд╛рдпрдХ рд╕рдВрдкрд╛рджрдХ , рдФрд░ рдмрд╛рдИрдВ рдУрд░ рдХреЛрдб рдореЗрдВ рдЦреБрд▓рддрд╛ рд╣реИред
рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдмрд┐рд▓реНрдбрд░ рдореЗрдВ рд▓реЗрдмрд▓ рдкрд░
рдЯреЗрдХреНрд╕реНрдЯрд▓реЗрдмреЗрд▓ рдХреЗ рдмрд╛рдИрдВ рдУрд░ рд╕рд░реНрдХрд▓ рдЦреАрдВрдЪреЗрдВред рдЙрд╕реА рддрд░рд╣, рдХреНрд░рдорд╢рдГ, рдмрд╛рдПрдВ, рджрд╛рдПрдВ, рдФрд░ рдиреАрдЪреЗ рдмрдЯрди рдХреЗ рд╕рд╛рде
рдкрд┐рдЫрд▓реЗ ,
рдЕрдЧрд▓реЗ рдФрд░
рдЫреЛрдбрд╝ рддрд░реАрдХреЛрдВ рдХреЛ рдорд┐рд▓рд╛рдПрдВред

рдЕрдкрдирд╛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд▓реЙрдиреНрдЪ рдХрд░реЗрдВред

рд╣рдордиреЗ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдкреЙрдкрдЕрдк рдЖрдХрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ред рдпрджрд┐ рдЖрдк рдПрдХ рдмрдбрд╝рд╛ рдпрд╛ рдЫреЛрдЯрд╛ рдкреЙрдкрдЕрдк рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЗрд╕реЗ
рд╕реНрдЯреЛрд░реАрдмреЛрд░реНрдб рдореЗрдВ рдЖрдХрд╛рд░ рджреЗрдВред
рдмрдЯрди рдХреЗ рд▓рд┐рдП рдПрдХ рдХреЛрдб рд▓рд┐рдЦрдирд╛
рдпрджрд┐ рдЖрдкрдиреЗ
рд╕рд╣рд╛рдпрдХ рд╕рдВрдкрд╛рджрдХ рдХреЛ рдкрд╣рд▓реЗ рд╕реЗ рдЫрд┐рдкрд╛рдпрд╛ рдирд╣реАрдВ рд╣реИ, рддреЛ
Cmd-Return рдпрд╛ V
iew> Standard Editor> Show Standard Editor рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░реЗрдВQuotesViewController.swift рдЦреЛрд▓реЗрдВ рдФрд░ рд╡рд░реНрдЧ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЧреБрдг рдЬреЛрдбрд╝реЗрдВ:
let quotes = Quote.all var currentQuoteIndex: Int = 0 { didSet { updateQuote() } }
рдЙрджреНрдзрд░рдг рдЧреБрдг рдореЗрдВ рд╕рднреА рдЙрджреНрдзрд░рдг рд╢рд╛рдорд┐рд▓ рд╣реИрдВ, рдФрд░
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) }
рд╕рднреА рдЙрджреНрдзрд░рдгреЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ
рдЕрдЧрд▓рд╛ () рдФрд░
рдкрд┐рдЫрд▓рд╛ () рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдЪрдХреНрд░ред
рдкрдж рдЫреЛрдбрд╝рдирд╛ рдмрдВрдж рдХрд░ рджреЗрддрд╛ рд╣реИред
рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд▓реЙрдиреНрдЪ рдХрд░реЗрдВ:

рдШрдЯрдирд╛ рдХреА рдирд┐рдЧрд░рд╛рдиреА
рдПрдХ рдФрд░ рдЪреАрдЬ рд╣реИ рдЬреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╣рдорд╛рд░реЗ рдЖрд╡реЗрджрди рд╕реЗ рдЙрдореНрдореАрдж рдХрд░рддреЗ рд╣реИрдВ - рдЬрдм рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрд╕рдХреЗ рдмрд╛рд╣рд░ рдХрд╣реАрдВ рдХреНрд▓рд┐рдХ рдХрд░рддрд╛ рд╣реИ рддреЛ рдкреЙрдк-рдЕрдк рд╡рд┐рдВрдбреЛ рдЫрд┐рдкрд╛рдПрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ
macOS рдЧреНрд▓реЛрдмрд▓ рдЗрд╡реЗрдВрдЯ рдореЙрдирд┐рдЯрд░ рдирд╛рдордХ рдПрдХ рддрдВрддреНрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рдПрдХ рдирдИ рд╕реНрд╡рд┐рдлреНрдЯ рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдПрдВ, рдЗрд╕реЗ
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 } } }
рдЗрд╕ рд╡рд░реНрдЧ рдХреЗ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЛ рд╢реБрд░реВ рдХрд░рддреЗ рд╕рдордп, рд╣рдо рдЗрд╕реЗ рдПрдХ рдЗрд╡реЗрдВрдЯ рдорд╛рд╕реНрдХ рджреЗрддреЗ рд╣реИрдВ рдЬрд┐рд╕реЗ рд╣рдо (рдЬреИрд╕реЗ рдХрд┐рд╕реНрдЯреНрд░реЛрдХреНрд╕, рдорд╛рдЙрд╕ рд╡реНрд╣реАрд▓ рд╕реНрдХреНрд░реЙрд▓ рдЗрддреНрдпрд╛рджрд┐) рдФрд░ рдПрдХ рдЗрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рд╕реБрдиреЗрдВрдЧреЗред
рдЬрдм рд╣рдо рд╕реБрдирдирд╛ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реЛрддреЗ рд╣реИрдВ, рддреЛ
рдкреНрд░рд╛рд░рдВрдн рдХрд░реЗрдВ () рдХреЙрд▓
addGlobalMonitorForEventsMatchingMask (_: рд╣реИрдВрдбрд▓рд░ :) , рдЬреЛ рдЙрд╕ рд╡рд╕реНрддреБ рдХреЛ рд▓реМрдЯрд╛рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рд╣рдо рдмрдЪрд╛ рд░рд╣реЗ рд╣реИрдВред рдЬреИрд╕реЗ рд╣реА рдореБрдЦреМрдЯрд╛ рдореЗрдВ рдирд┐рд╣рд┐рдд рдШрдЯрдирд╛ рд╣реЛрддреА рд╣реИ, рд╕рд┐рд╕реНрдЯрдо рдЖрдкрдХреЗ рд╣реИрдВрдбрд▓рд░ рдХреЛ рдмреБрд▓рд╛рддрд╛ рд╣реИред
рдореЙрдирд┐рдЯрд░рд┐рдВрдЧ рдЗрд╡реЗрдВрдЯреНрд╕ рдХреЛ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП
рд░рд┐рдореВрд╡рд░ () рдХреЛ
рд╕реНрдЯреЙрдк () рдореЗрдВ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рд╣рдо рдЗрд╕реЗ рд╢реВрдиреНрдп рдкрд░
рд╕реЗрдЯ рдХрд░рдХреЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рд╣рдЯрд╛рддреЗ рд╣реИрдВред
рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдЬреЛ рдХреБрдЫ рднреА рд╣реИ рд╡рд╣ рд╕рд╣реА рд╕рдордп рдкрд░
рд╕реНрдЯрд╛рд░реНрдЯ () рдФрд░
рд╕реНрдЯреЙрдк () рдХреЛ рдХреЙрд▓
рдХрд░рдирд╛ рд╣реИ ред рд╡рд░реНрдЧ рднреА рд╕рдлрд╛рдИ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП deinitializer рдкрд░
рд╕реНрдЯреЙрдк () рдХрд╣рддрд╛ рд╣реИред
рдХрдиреЗрдХреНрдЯрд┐рдВрдЧ рдЗрд╡реЗрдВрдЯ рдореЙрдирд┐рдЯрд░
AppDelegate.swift рдХреЛ рдЕрдВрддрд┐рдо рдмрд╛рд░ рдЦреЛрд▓реЗрдВ рдФрд░ рдПрдХ рдирдИ рд╕рдВрдкрддреНрддрд┐ рдЬреЛрдбрд╝реЗрдВ:
var eventMonitor: EventMonitor?
рдлрд┐рд░ рдЗрд╕ рдХреЛрдб рдХреЛ
рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЙрдирд┐рдЯрд░ рдХреЗ рдЕрдВрдд рдореЗрдВ
рдИрд╡реЗрдВрдЯ рдореЙрдирд┐рдЯрд░ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬреЛрдбрд╝реЗрдВред
eventMonitor = EventMonitor(mask: [.leftMouseDown, .rightMouseDown]) { [weak self] event in if let strongSelf = self, strongSelf.popover.isShown { strongSelf.closePopover(sender: event) } }
рдЬрдм рдЖрдк рдмрд╛рдПрдБ рдпрд╛ рджрд╛рдПрдБ рдмрдЯрди рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рддреЗ рд╣реИрдВ рддреЛ рдпрд╣ рдЖрдкрдХреЗ рдЖрд╡реЗрджрди рдХреЛ рд╕реВрдЪрд┐рдд рдХрд░реЗрдЧрд╛ред рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ: рд╣реИрдВрдбрд▓рд░ рдХреЛ рдЖрдкрдХреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рдЕрдВрджрд░ рдорд╛рдЙрд╕ рдХреНрд▓рд┐рдХ рдХреЗ рдЬрд╡рд╛рдм рдореЗрдВ рдирд╣реАрдВ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдпрд╣реА рдХрд╛рд░рдг рд╣реИ рдХрд┐ рдЬрдм рдЖрдк рдЗрд╕рдХреЗ рдЕрдВрджрд░ рдХреНрд▓рд┐рдХ рдХрд░реЗрдВрдЧреЗ рддреЛ рдкреЙрдкрдЕрдк рдмрдВрдж рдирд╣реАрдВ рд╣реЛрдЧрд╛ред
AppDelegate рдФрд░
EventMonitor рдХреЗ рдмреАрдЪ рдордЬрдмреВрдд рд╕рдВрдмрдВрдзреЛрдВ рдХреЗ рдЪрдХреНрд░ рдХреЗ рдЦрддрд░реЗ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдо
рд╕реНрд╡рдпрдВ рдХреЗ рд▓рд┐рдП рдПрдХ
рдХрдордЬреЛрд░ рд╕рдВрджрд░реНрдн рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред
рд╢реЛрдкреЙрд╡рд░ рдХреЗ рдЕрдВрдд рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдЬреЛрдбрд╝реЗрдВ
(_ :) рд╡рд┐рдзрд┐:
eventMonitor?.start()
рдЬрдм рд╣рдо рдкреЙрдк-рдЕрдк рд╡рд┐рдВрдбреЛ рдкреНрд░рдХрдЯ рд╣реЛрддреЗ рд╣реИрдВ рддреЛ рд╣рдо рдШрдЯрдирд╛рдУрдВ рдХреА рдирд┐рдЧрд░рд╛рдиреА рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред
рдЕрдм рдХреЛрдб рдХреЛ
рдХреНрд▓реЛрдЬрд╝рдкреЙрд╡рд░ рдХреЗ рдЕрдВрдд рдореЗрдВ
рдЬреЛрдбрд╝реЗрдВ (_ :) рд╡рд┐рдзрд┐:
eventMonitor?.stop()
рдЬрдм рдкреЙрдкрдЕрдк рдмрдВрдж рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рд╣рдо рдореЙрдирд┐рдЯрд░рд┐рдВрдЧ рд╕рдорд╛рдкреНрдд рдХрд░ рджреЗрддреЗ рд╣реИрдВред
рдЖрд╡реЗрджрди рддреИрдпрд╛рд░ рд╣реИ!
рдирд┐рд╖реНрдХрд░реНрд╖
рдпрд╣рд╛рдВ рдЖрдкрдХреЛ рдЗрд╕ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХрд╛ рдкреВрд░рд╛ рдХреЛрдб рдорд┐рд▓реЗрдЧрд╛ред
рдЖрдкрдиреЗ рдореЗрдиреВ рдмрд╛рд░ рдкрд░ рд╕реНрдерд┐рдд рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдореЗрдиреВ рдФрд░ рдкреЙрдк-рдЕрдк рд╕реЗрдЯ рдХрд░рдирд╛ рд╕реАрдЦ рд▓рд┐рдпрд╛ рд╣реИред рдЙрджреНрдзрд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдмреЗрд╣рддрд░ рд▓реБрдХ рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдИ рдЯреИрдЧ рдпрд╛ рд╕реНрд╡рд░реВрдкрд┐рдд рдкрд╛рда рдХреЗ рд╕рд╛рде рдкреНрд░рдпреЛрдЧ рдХреНрдпреЛрдВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ? рдпрд╛ рдЗрдВрдЯрд░рдиреЗрдЯ рд╕реЗ рдЙрджреНрдзрд░рдг рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмреИрдХрдПрдВрдб рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВ? рдпрд╛ рдХреНрдпрд╛ рдЖрдк рдХреАрдмреЛрд░реНрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдЙрджреНрдзрд░рдгреЛрдВ рдХреЗ рдмреАрдЪ рдиреЗрд╡рд┐рдЧреЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ?
рдЕрдиреБрд╕рдВрдзрд╛рди рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдЪреНрдЫреА рдЬрдЧрд╣ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рджрд╕реНрддрд╛рд╡реЗрдЬ рд╣реИ:
NSMenu ,
NSPopover рдФрд░
NSStatusItem ред