├── .gitignore ├── Cocoa Binding ├── Cocoa Binding.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── szabolcs.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── szabolcs.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── Cocoa Binding │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Base.lproj │ │ └── Main.storyboard │ ├── Cocoa_Binding.entitlements │ ├── Info.plist │ ├── Person.swift │ └── ViewController.swift ├── CocoaBindings.png └── ReadMe.md ├── CustomAnnotations ├── CustomAnnotations.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── szabolcs.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── szabolcs.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── CustomAnnotations │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ ├── Contents.json │ │ └── windshock.imageset │ │ │ ├── Contents.json │ │ │ ├── windshock_day@2x-1.png │ │ │ ├── windshock_day@2x.png │ │ │ └── windshock_night@2x.png │ ├── Base.lproj │ │ └── Main.storyboard │ ├── CustomAnnotations.entitlements │ ├── Info.plist │ └── ViewController.swift ├── ReadMe.md └── overlay.png ├── KVC ├── KVC.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── szabolcs.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── szabolcs.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── KVC │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Base.lproj │ │ └── Main.storyboard │ ├── Info.plist │ ├── KVC.entitlements │ └── ViewController.swift ├── ReadMe.md └── Thermostat.png ├── MapKitmacOS ├── MapKit.png ├── MapKitmacOS.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── szabolcs.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── szabolcs.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── MapKitmacOS │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Base.lproj │ │ └── Main.storyboard │ ├── Info.plist │ ├── MapKitmacOS.entitlements │ └── ViewController.swift └── ReadMe.md ├── NSCollectionView ├── NSCollectionView.png ├── NSCollectionView.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── szabolcs.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── szabolcs.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── NSCollectionView │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Base.lproj │ │ └── Main.storyboard │ ├── Info.plist │ ├── Item.swift │ ├── Item.xib │ ├── NSCollectionView.entitlements │ └── ViewController.swift └── ReadMe.md ├── NSOutlineView ├── NSOutlineView.png ├── NSOutlineView.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── szabolcs.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── szabolcs.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ ├── NSOutlineView.xcscheme │ │ └── xcschememanagement.plist ├── NSOutlineView │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ └── Main.storyboard │ ├── Info.plist │ ├── Person.swift │ └── ViewController.swift └── ReadMe.md ├── NSTabView ├── NSTabView.png ├── NSTabView.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── szabolcs.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── szabolcs.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── NSTabView │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── line _chart.imageset │ │ │ ├── Contents.json │ │ │ └── line _chart@2x.png │ │ ├── line _chart_XXL.imageset │ │ │ ├── Contents.json │ │ │ └── line _chart_XXL@2x.png │ │ ├── pie_chart.imageset │ │ │ ├── Contents.json │ │ │ └── pie_chart@2x.png │ │ └── pie_chart_XXL.imageset │ │ │ ├── Contents.json │ │ │ └── pie_chart_XXL@2x.png │ ├── Base.lproj │ │ └── Main.storyboard │ ├── Info.plist │ ├── NSTabView.entitlements │ ├── ViewController.swift │ └── WindowController.swift └── ReadMe.md ├── NSTableView ├── NSTableView.png ├── NSTableView.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── szabolcs.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── szabolcs.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── NSTableView │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Base.lproj │ │ └── Main.storyboard │ ├── Info.plist │ ├── NSTableView.entitlements │ └── ViewController.swift └── ReadMe.md ├── NSTableView1 ├── NSTableView.png ├── NSTableView1.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── szabolcs.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── szabolcs.xcuserdatad │ │ └── xcschemes │ │ ├── NSTableView1.xcscheme │ │ └── xcschememanagement.plist ├── NSTableView1 │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ └── Main.storyboard │ ├── Info.plist │ ├── Person.swift │ └── ViewController.swift └── ReadMe.md ├── NSTableViewWithLoad ├── NSTableView1.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── szabolcs.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── szabolcs.xcuserdatad │ │ └── xcschemes │ │ ├── NSTableView1.xcscheme │ │ └── xcschememanagement.plist ├── NSTableView1 │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ └── Main.storyboard │ ├── Info.plist │ ├── Person.swift │ └── ViewController.swift └── ReadMe.md ├── PaintCode ├── PaintCode.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── szabolcs.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── szabolcs.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── PaintCode │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Base.lproj │ │ └── Main.storyboard │ ├── Info.plist │ ├── Origami.swift │ ├── PaintCode.entitlements │ ├── PaintCode.swift │ └── ViewController.swift ├── PaintCode1.png └── ReadMe.md ├── ReadMe.md ├── SemiStoryboard ├── ReadMe.md ├── SemiStoryboard.png ├── SemiStoryboard.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── szabolcs.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── szabolcs.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist └── SemiStoryboard │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json │ ├── Base.lproj │ └── Main.storyboard │ ├── Info.plist │ ├── MainWindow.swift │ ├── MainWindowController.swift │ ├── MyViewController.swift │ └── SemiStoryboard.entitlements ├── SlidingView ├── README.md ├── SlidingView.png ├── SlidingViews.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── szabolcs.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── szabolcs.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist └── SlidingViews │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json │ ├── Base.lproj │ └── Main.storyboard │ ├── Info.plist │ ├── SlidingViews.entitlements │ └── ViewController.swift ├── SourceListView ├── ReadMe.md ├── SourceListView.png ├── SourceListView.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── szabolcs.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── szabolcs.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ ├── SourceListView.xcscheme │ │ └── xcschememanagement.plist └── SourceListView │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── Germany.imageset │ │ ├── Contents.json │ │ └── Germany.png │ ├── Hungary.imageset │ │ ├── Contents.json │ │ └── Hungary.png │ ├── Japan.imageset │ │ ├── Contents.json │ │ └── Japan.png │ └── Mexico.imageset │ │ ├── Contents.json │ │ └── Mexico.png │ ├── Base.lproj │ └── Main.storyboard │ ├── Country.swift │ ├── Info.plist │ └── ViewController.swift └── SplitViewController ├── ReadMe.md ├── SplitViewController.png └── SplitViewController ├── SplitViewController.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── szabolcs.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── szabolcs.xcuserdatad │ └── xcschemes │ └── xcschememanagement.plist └── SplitViewController ├── AppDelegate.swift ├── Assets.xcassets ├── AppIcon.appiconset │ └── Contents.json └── Contents.json ├── Base.lproj └── Main.storyboard ├── DetailViewController.swift ├── Info.plist ├── Person.swift ├── SplitViewController.entitlements └── ViewController.swift /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /Cocoa Binding/Cocoa Binding.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Cocoa Binding/Cocoa Binding.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Cocoa Binding/Cocoa Binding.xcodeproj/project.xcworkspace/xcuserdata/szabolcs.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/Cocoa Binding/Cocoa Binding.xcodeproj/project.xcworkspace/xcuserdata/szabolcs.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Cocoa Binding/Cocoa Binding.xcodeproj/xcuserdata/szabolcs.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Cocoa Binding.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Cocoa Binding/Cocoa Binding/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Cocoa Binding 4 | // 5 | // Created by Szabolcs Toth on 30/04/2020. 6 | // Copyright © 2020 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject, NSApplicationDelegate { 13 | 14 | 15 | 16 | func applicationDidFinishLaunching(_ aNotification: Notification) { 17 | // Insert code here to initialize your application 18 | } 19 | 20 | func applicationWillTerminate(_ aNotification: Notification) { 21 | // Insert code here to tear down your application 22 | } 23 | 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /Cocoa Binding/Cocoa Binding/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "scale" : "1x", 6 | "size" : "16x16" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "scale" : "2x", 11 | "size" : "16x16" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "scale" : "1x", 16 | "size" : "32x32" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "scale" : "2x", 21 | "size" : "32x32" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "scale" : "1x", 26 | "size" : "128x128" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "scale" : "2x", 31 | "size" : "128x128" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "scale" : "1x", 36 | "size" : "256x256" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "scale" : "2x", 41 | "size" : "256x256" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "scale" : "1x", 46 | "size" : "512x512" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "scale" : "2x", 51 | "size" : "512x512" 52 | } 53 | ], 54 | "info" : { 55 | "author" : "xcode", 56 | "version" : 1 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Cocoa Binding/Cocoa Binding/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Cocoa Binding/Cocoa Binding/Cocoa_Binding.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Cocoa Binding/Cocoa Binding/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2020 purzelbaum.hu. All rights reserved. 27 | NSMainStoryboardFile 28 | Main 29 | NSPrincipalClass 30 | NSApplication 31 | NSSupportsAutomaticTermination 32 | 33 | NSSupportsSuddenTermination 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /Cocoa Binding/Cocoa Binding/Person.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Person.swift 3 | // Cocoa Binding 4 | // 5 | // Created by Szabolcs Toth on 30/04/2020. 6 | // Copyright © 2020 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class Person: NSObject { 12 | @objc dynamic var firstName: String 13 | @objc dynamic var lastName: String 14 | @objc dynamic var mobileNumber: String 15 | 16 | init(firstName: String, lastName: String, mobileNumber: String) { 17 | self.firstName = firstName 18 | self.lastName = lastName 19 | self.mobileNumber = mobileNumber 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Cocoa Binding/Cocoa Binding/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Cocoa Binding 4 | // 5 | // Created by Szabolcs Toth on 30/04/2020. 6 | // Copyright © 2020 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class ViewController: NSViewController { 12 | 13 | @objc dynamic var peopleArray: [Person] = [Person(firstName: "Ragnar", lastName: "Lothbrok", mobileNumber: "555-12347"), 14 | Person(firstName: "Bjorn", lastName: "Lothbrok", mobileNumber: "555-34129"), 15 | Person(firstName: "Harald", lastName: "Finehair", mobileNumber: "555-45128") 16 | ] 17 | 18 | override func viewDidLoad() { 19 | super.viewDidLoad() 20 | 21 | // Do any additional setup after loading the view. 22 | } 23 | 24 | override var representedObject: Any? { 25 | didSet { 26 | // Update the view, if already loaded. 27 | } 28 | } 29 | 30 | 31 | } 32 | 33 | -------------------------------------------------------------------------------- /Cocoa Binding/CocoaBindings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/Cocoa Binding/CocoaBindings.png -------------------------------------------------------------------------------- /Cocoa Binding/ReadMe.md: -------------------------------------------------------------------------------- 1 | ## NSTableView Sample with Cocoa Bindings 2 | 3 | ![CocoaBindings](CocoaBindings.png) 4 | 5 | A very simple NSTableView using as less code as possible :) 6 | 7 | You can the tutorial about it [here](https://kicsipixel.github.io/2020/bindings/) 8 | -------------------------------------------------------------------------------- /CustomAnnotations/CustomAnnotations.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CustomAnnotations/CustomAnnotations.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /CustomAnnotations/CustomAnnotations.xcodeproj/project.xcworkspace/xcuserdata/szabolcs.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/CustomAnnotations/CustomAnnotations.xcodeproj/project.xcworkspace/xcuserdata/szabolcs.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /CustomAnnotations/CustomAnnotations.xcodeproj/xcuserdata/szabolcs.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | CustomAnnotations.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /CustomAnnotations/CustomAnnotations/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // CustomAnnotations 4 | // 5 | // Created by Szabolcs Toth on 06/11/2019. 6 | // Copyright © 2019 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject, NSApplicationDelegate { 13 | 14 | 15 | 16 | func applicationDidFinishLaunching(_ aNotification: Notification) { 17 | // Insert code here to initialize your application 18 | } 19 | 20 | func applicationWillTerminate(_ aNotification: Notification) { 21 | // Insert code here to tear down your application 22 | } 23 | 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /CustomAnnotations/CustomAnnotations/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /CustomAnnotations/CustomAnnotations/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /CustomAnnotations/CustomAnnotations/Assets.xcassets/windshock.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "1x", 10 | "appearances" : [ 11 | { 12 | "appearance" : "luminosity", 13 | "value" : "light" 14 | } 15 | ] 16 | }, 17 | { 18 | "idiom" : "universal", 19 | "scale" : "1x", 20 | "appearances" : [ 21 | { 22 | "appearance" : "luminosity", 23 | "value" : "dark" 24 | } 25 | ] 26 | }, 27 | { 28 | "idiom" : "universal", 29 | "filename" : "windshock_day@2x-1.png", 30 | "scale" : "2x" 31 | }, 32 | { 33 | "idiom" : "universal", 34 | "filename" : "windshock_day@2x.png", 35 | "appearances" : [ 36 | { 37 | "appearance" : "luminosity", 38 | "value" : "light" 39 | } 40 | ], 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "universal", 45 | "filename" : "windshock_night@2x.png", 46 | "appearances" : [ 47 | { 48 | "appearance" : "luminosity", 49 | "value" : "dark" 50 | } 51 | ], 52 | "scale" : "2x" 53 | }, 54 | { 55 | "idiom" : "universal", 56 | "scale" : "3x" 57 | }, 58 | { 59 | "idiom" : "universal", 60 | "scale" : "3x", 61 | "appearances" : [ 62 | { 63 | "appearance" : "luminosity", 64 | "value" : "light" 65 | } 66 | ] 67 | }, 68 | { 69 | "idiom" : "universal", 70 | "scale" : "3x", 71 | "appearances" : [ 72 | { 73 | "appearance" : "luminosity", 74 | "value" : "dark" 75 | } 76 | ] 77 | } 78 | ], 79 | "info" : { 80 | "version" : 1, 81 | "author" : "xcode" 82 | } 83 | } -------------------------------------------------------------------------------- /CustomAnnotations/CustomAnnotations/Assets.xcassets/windshock.imageset/windshock_day@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/CustomAnnotations/CustomAnnotations/Assets.xcassets/windshock.imageset/windshock_day@2x-1.png -------------------------------------------------------------------------------- /CustomAnnotations/CustomAnnotations/Assets.xcassets/windshock.imageset/windshock_day@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/CustomAnnotations/CustomAnnotations/Assets.xcassets/windshock.imageset/windshock_day@2x.png -------------------------------------------------------------------------------- /CustomAnnotations/CustomAnnotations/Assets.xcassets/windshock.imageset/windshock_night@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/CustomAnnotations/CustomAnnotations/Assets.xcassets/windshock.imageset/windshock_night@2x.png -------------------------------------------------------------------------------- /CustomAnnotations/CustomAnnotations/CustomAnnotations.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | com.apple.security.network.client 10 | 11 | com.apple.security.network.server 12 | 13 | com.apple.security.personal-information.location 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /CustomAnnotations/CustomAnnotations/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2019 purzelbaum.hu. All rights reserved. 27 | NSMainStoryboardFile 28 | Main 29 | NSPrincipalClass 30 | NSApplication 31 | NSSupportsAutomaticTermination 32 | 33 | NSSupportsSuddenTermination 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /CustomAnnotations/CustomAnnotations/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // CustomAnnotations 4 | // 5 | // Created by Szabolcs Toth on 06/11/2019. 6 | // Copyright © 2019 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import MapKit 11 | import CoreLocation 12 | 13 | class ViewController: NSViewController { 14 | 15 | @IBOutlet var mapView: MKMapView! 16 | let locationManager = CLLocationManager() 17 | let regionMeter: Double = 10000 18 | 19 | override func viewDidLoad() { 20 | super.viewDidLoad() 21 | checkLocationServices() 22 | } 23 | 24 | func setupLocationManager() { 25 | locationManager.delegate = self 26 | locationManager.desiredAccuracy = kCLLocationAccuracyBest 27 | } 28 | 29 | func checkLocationServices() { 30 | if CLLocationManager.locationServicesEnabled() { 31 | setupLocationManager() 32 | checkLocationAutherization() 33 | } else { 34 | showAlert(issue: "not enabled") 35 | } 36 | } 37 | 38 | func centerViewOnUserLocation() { 39 | if let location = locationManager.location?.coordinate { 40 | let region = MKCoordinateRegion.init(center: location, latitudinalMeters: regionMeter, longitudinalMeters: regionMeter) 41 | mapView.setRegion(region, animated: true) 42 | } 43 | } 44 | 45 | func checkLocationAutherization() { 46 | switch CLLocationManager.authorizationStatus() { 47 | case .authorized: 48 | addAnnotations() 49 | break 50 | case .denied: 51 | showAlert(issue: "denied") 52 | break 53 | case .notDetermined: 54 | locationManager.requestAlwaysAuthorization() 55 | break 56 | case .restricted: 57 | showAlert(issue: "restricted") 58 | break 59 | case .authorizedAlways: 60 | break 61 | @unknown default: 62 | break 63 | } 64 | } 65 | 66 | func showAlert(issue: String) { 67 | let alert = NSAlert() 68 | 69 | switch issue { 70 | case "not enabled": 71 | alert.messageText = "Enable Location Services" 72 | alert.informativeText = "Location services are not enabled. Please, check it in your Sytem Preferences." 73 | _ = alert.runModal() 74 | case "denied": 75 | alert.messageText = "Enable Location Services" 76 | alert.informativeText = "Location services are denied. Please, check it in your Sytem Preferences." 77 | _ = alert.runModal() 78 | default: 79 | alert.messageText = "Enable Location Services" 80 | alert.informativeText = "Location services are restricted. Please, check it in your Sytem Preferences." 81 | _ = alert.runModal() 82 | } 83 | } 84 | 85 | func addAnnotations() { 86 | let airportDeparture = MKPointAnnotation() 87 | airportDeparture.title = "BUD" 88 | airportDeparture.coordinate = CLLocationCoordinate2D(latitude: 47.439444, longitude: 19.261944) 89 | 90 | let airportArrival = MKPointAnnotation() 91 | airportArrival.title = "FRA" 92 | airportArrival.coordinate = CLLocationCoordinate2D(latitude: 50.033333, longitude: 8.570556) 93 | let locationsArray: [MKPointAnnotation] = [airportDeparture, airportArrival ] 94 | 95 | mapView.showAnnotations(locationsArray, animated: true) 96 | mapView.setRegion(regionFor(coordinates: [airportArrival.coordinate, airportDeparture.coordinate]), animated: true) 97 | 98 | var locations = locationsArray.map { $0.coordinate } 99 | let polyline = MKPolyline(coordinates: &locations, count: locations.count) 100 | mapView?.addOverlay(polyline) 101 | 102 | } 103 | 104 | func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer { 105 | if overlay is MKPolyline { 106 | let renderer = MKPolylineRenderer(overlay: overlay) 107 | renderer.strokeColor = NSColor.white 108 | renderer.lineWidth = 1 109 | return renderer 110 | } 111 | 112 | return MKOverlayRenderer() 113 | } 114 | 115 | // Source: https://stackoverflow.com/questions/1336370/positioning-mkmapview-to-show-multiple-annotations-at-once/1343448 116 | 117 | func regionFor(coordinates coords: [CLLocationCoordinate2D]) -> MKCoordinateRegion { 118 | var r = MKMapRect.null 119 | 120 | for i in 0 ..< coords.count { 121 | let p = MKMapPoint(coords[i]) 122 | 123 | r = r.union(MKMapRect(x: p.x, y: p.y, width: 0, height: 0)) 124 | } 125 | 126 | return MKCoordinateRegion(r) 127 | } 128 | 129 | } 130 | 131 | extension ViewController: CLLocationManagerDelegate { 132 | 133 | func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { 134 | checkLocationAutherization() 135 | } 136 | } 137 | 138 | extension ViewController: MKMapViewDelegate { 139 | func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { 140 | 141 | var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "AnnotationView") 142 | 143 | if annotationView == nil { 144 | annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: "AnnotationView") 145 | } 146 | 147 | annotationView?.image = NSImage(named: "windshock") 148 | 149 | return annotationView 150 | } 151 | } 152 | 153 | -------------------------------------------------------------------------------- /CustomAnnotations/ReadMe.md: -------------------------------------------------------------------------------- 1 | ## MapKit with custom annotations and overlay on macOS 2 | 3 | ![Overlay](overlay.png) 4 | 5 | Sources: 6 | - [AppCoda](https://www.appcoda.com/mapkit-polyline-polygon/) 7 | - [raywenderlich.com](https://www.raywenderlich.com/425-mapkit-tutorial-overlay-views) 8 | -------------------------------------------------------------------------------- /CustomAnnotations/overlay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/CustomAnnotations/overlay.png -------------------------------------------------------------------------------- /KVC/KVC.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 57AFF6132486B9AE00D121B6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57AFF6122486B9AE00D121B6 /* AppDelegate.swift */; }; 11 | 57AFF6152486B9AE00D121B6 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57AFF6142486B9AE00D121B6 /* ViewController.swift */; }; 12 | 57AFF6172486B9B200D121B6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 57AFF6162486B9B200D121B6 /* Assets.xcassets */; }; 13 | 57AFF61A2486B9B200D121B6 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 57AFF6182486B9B200D121B6 /* Main.storyboard */; }; 14 | /* End PBXBuildFile section */ 15 | 16 | /* Begin PBXFileReference section */ 17 | 57AFF60F2486B9AE00D121B6 /* KVC.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = KVC.app; sourceTree = BUILT_PRODUCTS_DIR; }; 18 | 57AFF6122486B9AE00D121B6 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 19 | 57AFF6142486B9AE00D121B6 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 20 | 57AFF6162486B9B200D121B6 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 21 | 57AFF6192486B9B200D121B6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 22 | 57AFF61B2486B9B200D121B6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 23 | 57AFF61C2486B9B200D121B6 /* KVC.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = KVC.entitlements; sourceTree = ""; }; 24 | /* End PBXFileReference section */ 25 | 26 | /* Begin PBXFrameworksBuildPhase section */ 27 | 57AFF60C2486B9AE00D121B6 /* Frameworks */ = { 28 | isa = PBXFrameworksBuildPhase; 29 | buildActionMask = 2147483647; 30 | files = ( 31 | ); 32 | runOnlyForDeploymentPostprocessing = 0; 33 | }; 34 | /* End PBXFrameworksBuildPhase section */ 35 | 36 | /* Begin PBXGroup section */ 37 | 57AFF6062486B9AE00D121B6 = { 38 | isa = PBXGroup; 39 | children = ( 40 | 57AFF6112486B9AE00D121B6 /* KVC */, 41 | 57AFF6102486B9AE00D121B6 /* Products */, 42 | ); 43 | sourceTree = ""; 44 | }; 45 | 57AFF6102486B9AE00D121B6 /* Products */ = { 46 | isa = PBXGroup; 47 | children = ( 48 | 57AFF60F2486B9AE00D121B6 /* KVC.app */, 49 | ); 50 | name = Products; 51 | sourceTree = ""; 52 | }; 53 | 57AFF6112486B9AE00D121B6 /* KVC */ = { 54 | isa = PBXGroup; 55 | children = ( 56 | 57AFF6122486B9AE00D121B6 /* AppDelegate.swift */, 57 | 57AFF6142486B9AE00D121B6 /* ViewController.swift */, 58 | 57AFF6162486B9B200D121B6 /* Assets.xcassets */, 59 | 57AFF6182486B9B200D121B6 /* Main.storyboard */, 60 | 57AFF61B2486B9B200D121B6 /* Info.plist */, 61 | 57AFF61C2486B9B200D121B6 /* KVC.entitlements */, 62 | ); 63 | path = KVC; 64 | sourceTree = ""; 65 | }; 66 | /* End PBXGroup section */ 67 | 68 | /* Begin PBXNativeTarget section */ 69 | 57AFF60E2486B9AE00D121B6 /* KVC */ = { 70 | isa = PBXNativeTarget; 71 | buildConfigurationList = 57AFF61F2486B9B200D121B6 /* Build configuration list for PBXNativeTarget "KVC" */; 72 | buildPhases = ( 73 | 57AFF60B2486B9AE00D121B6 /* Sources */, 74 | 57AFF60C2486B9AE00D121B6 /* Frameworks */, 75 | 57AFF60D2486B9AE00D121B6 /* Resources */, 76 | ); 77 | buildRules = ( 78 | ); 79 | dependencies = ( 80 | ); 81 | name = KVC; 82 | productName = KVC; 83 | productReference = 57AFF60F2486B9AE00D121B6 /* KVC.app */; 84 | productType = "com.apple.product-type.application"; 85 | }; 86 | /* End PBXNativeTarget section */ 87 | 88 | /* Begin PBXProject section */ 89 | 57AFF6072486B9AE00D121B6 /* Project object */ = { 90 | isa = PBXProject; 91 | attributes = { 92 | LastSwiftUpdateCheck = 1150; 93 | LastUpgradeCheck = 1150; 94 | ORGANIZATIONNAME = purzelbaum.hu; 95 | TargetAttributes = { 96 | 57AFF60E2486B9AE00D121B6 = { 97 | CreatedOnToolsVersion = 11.5; 98 | }; 99 | }; 100 | }; 101 | buildConfigurationList = 57AFF60A2486B9AE00D121B6 /* Build configuration list for PBXProject "KVC" */; 102 | compatibilityVersion = "Xcode 9.3"; 103 | developmentRegion = en; 104 | hasScannedForEncodings = 0; 105 | knownRegions = ( 106 | en, 107 | Base, 108 | ); 109 | mainGroup = 57AFF6062486B9AE00D121B6; 110 | productRefGroup = 57AFF6102486B9AE00D121B6 /* Products */; 111 | projectDirPath = ""; 112 | projectRoot = ""; 113 | targets = ( 114 | 57AFF60E2486B9AE00D121B6 /* KVC */, 115 | ); 116 | }; 117 | /* End PBXProject section */ 118 | 119 | /* Begin PBXResourcesBuildPhase section */ 120 | 57AFF60D2486B9AE00D121B6 /* Resources */ = { 121 | isa = PBXResourcesBuildPhase; 122 | buildActionMask = 2147483647; 123 | files = ( 124 | 57AFF6172486B9B200D121B6 /* Assets.xcassets in Resources */, 125 | 57AFF61A2486B9B200D121B6 /* Main.storyboard in Resources */, 126 | ); 127 | runOnlyForDeploymentPostprocessing = 0; 128 | }; 129 | /* End PBXResourcesBuildPhase section */ 130 | 131 | /* Begin PBXSourcesBuildPhase section */ 132 | 57AFF60B2486B9AE00D121B6 /* Sources */ = { 133 | isa = PBXSourcesBuildPhase; 134 | buildActionMask = 2147483647; 135 | files = ( 136 | 57AFF6152486B9AE00D121B6 /* ViewController.swift in Sources */, 137 | 57AFF6132486B9AE00D121B6 /* AppDelegate.swift in Sources */, 138 | ); 139 | runOnlyForDeploymentPostprocessing = 0; 140 | }; 141 | /* End PBXSourcesBuildPhase section */ 142 | 143 | /* Begin PBXVariantGroup section */ 144 | 57AFF6182486B9B200D121B6 /* Main.storyboard */ = { 145 | isa = PBXVariantGroup; 146 | children = ( 147 | 57AFF6192486B9B200D121B6 /* Base */, 148 | ); 149 | name = Main.storyboard; 150 | sourceTree = ""; 151 | }; 152 | /* End PBXVariantGroup section */ 153 | 154 | /* Begin XCBuildConfiguration section */ 155 | 57AFF61D2486B9B200D121B6 /* Debug */ = { 156 | isa = XCBuildConfiguration; 157 | buildSettings = { 158 | ALWAYS_SEARCH_USER_PATHS = NO; 159 | CLANG_ANALYZER_NONNULL = YES; 160 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 161 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 162 | CLANG_CXX_LIBRARY = "libc++"; 163 | CLANG_ENABLE_MODULES = YES; 164 | CLANG_ENABLE_OBJC_ARC = YES; 165 | CLANG_ENABLE_OBJC_WEAK = YES; 166 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 167 | CLANG_WARN_BOOL_CONVERSION = YES; 168 | CLANG_WARN_COMMA = YES; 169 | CLANG_WARN_CONSTANT_CONVERSION = YES; 170 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 171 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 172 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 173 | CLANG_WARN_EMPTY_BODY = YES; 174 | CLANG_WARN_ENUM_CONVERSION = YES; 175 | CLANG_WARN_INFINITE_RECURSION = YES; 176 | CLANG_WARN_INT_CONVERSION = YES; 177 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 178 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 179 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 180 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 181 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 182 | CLANG_WARN_STRICT_PROTOTYPES = YES; 183 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 184 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 185 | CLANG_WARN_UNREACHABLE_CODE = YES; 186 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 187 | COPY_PHASE_STRIP = NO; 188 | DEBUG_INFORMATION_FORMAT = dwarf; 189 | ENABLE_STRICT_OBJC_MSGSEND = YES; 190 | ENABLE_TESTABILITY = YES; 191 | GCC_C_LANGUAGE_STANDARD = gnu11; 192 | GCC_DYNAMIC_NO_PIC = NO; 193 | GCC_NO_COMMON_BLOCKS = YES; 194 | GCC_OPTIMIZATION_LEVEL = 0; 195 | GCC_PREPROCESSOR_DEFINITIONS = ( 196 | "DEBUG=1", 197 | "$(inherited)", 198 | ); 199 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 200 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 201 | GCC_WARN_UNDECLARED_SELECTOR = YES; 202 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 203 | GCC_WARN_UNUSED_FUNCTION = YES; 204 | GCC_WARN_UNUSED_VARIABLE = YES; 205 | MACOSX_DEPLOYMENT_TARGET = 10.15; 206 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 207 | MTL_FAST_MATH = YES; 208 | ONLY_ACTIVE_ARCH = YES; 209 | SDKROOT = macosx; 210 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 211 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 212 | }; 213 | name = Debug; 214 | }; 215 | 57AFF61E2486B9B200D121B6 /* Release */ = { 216 | isa = XCBuildConfiguration; 217 | buildSettings = { 218 | ALWAYS_SEARCH_USER_PATHS = NO; 219 | CLANG_ANALYZER_NONNULL = YES; 220 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 221 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 222 | CLANG_CXX_LIBRARY = "libc++"; 223 | CLANG_ENABLE_MODULES = YES; 224 | CLANG_ENABLE_OBJC_ARC = YES; 225 | CLANG_ENABLE_OBJC_WEAK = YES; 226 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 227 | CLANG_WARN_BOOL_CONVERSION = YES; 228 | CLANG_WARN_COMMA = YES; 229 | CLANG_WARN_CONSTANT_CONVERSION = YES; 230 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 231 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 232 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 233 | CLANG_WARN_EMPTY_BODY = YES; 234 | CLANG_WARN_ENUM_CONVERSION = YES; 235 | CLANG_WARN_INFINITE_RECURSION = YES; 236 | CLANG_WARN_INT_CONVERSION = YES; 237 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 238 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 239 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 240 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 241 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 242 | CLANG_WARN_STRICT_PROTOTYPES = YES; 243 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 244 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 245 | CLANG_WARN_UNREACHABLE_CODE = YES; 246 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 247 | COPY_PHASE_STRIP = NO; 248 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 249 | ENABLE_NS_ASSERTIONS = NO; 250 | ENABLE_STRICT_OBJC_MSGSEND = YES; 251 | GCC_C_LANGUAGE_STANDARD = gnu11; 252 | GCC_NO_COMMON_BLOCKS = YES; 253 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 254 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 255 | GCC_WARN_UNDECLARED_SELECTOR = YES; 256 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 257 | GCC_WARN_UNUSED_FUNCTION = YES; 258 | GCC_WARN_UNUSED_VARIABLE = YES; 259 | MACOSX_DEPLOYMENT_TARGET = 10.15; 260 | MTL_ENABLE_DEBUG_INFO = NO; 261 | MTL_FAST_MATH = YES; 262 | SDKROOT = macosx; 263 | SWIFT_COMPILATION_MODE = wholemodule; 264 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 265 | }; 266 | name = Release; 267 | }; 268 | 57AFF6202486B9B200D121B6 /* Debug */ = { 269 | isa = XCBuildConfiguration; 270 | buildSettings = { 271 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 272 | CODE_SIGN_ENTITLEMENTS = KVC/KVC.entitlements; 273 | CODE_SIGN_STYLE = Automatic; 274 | COMBINE_HIDPI_IMAGES = YES; 275 | DEVELOPMENT_TEAM = 358WHQF94W; 276 | ENABLE_HARDENED_RUNTIME = YES; 277 | INFOPLIST_FILE = KVC/Info.plist; 278 | LD_RUNPATH_SEARCH_PATHS = ( 279 | "$(inherited)", 280 | "@executable_path/../Frameworks", 281 | ); 282 | PRODUCT_BUNDLE_IDENTIFIER = hu.purzelbaum.KVC; 283 | PRODUCT_NAME = "$(TARGET_NAME)"; 284 | SWIFT_VERSION = 5.0; 285 | }; 286 | name = Debug; 287 | }; 288 | 57AFF6212486B9B200D121B6 /* Release */ = { 289 | isa = XCBuildConfiguration; 290 | buildSettings = { 291 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 292 | CODE_SIGN_ENTITLEMENTS = KVC/KVC.entitlements; 293 | CODE_SIGN_STYLE = Automatic; 294 | COMBINE_HIDPI_IMAGES = YES; 295 | DEVELOPMENT_TEAM = 358WHQF94W; 296 | ENABLE_HARDENED_RUNTIME = YES; 297 | INFOPLIST_FILE = KVC/Info.plist; 298 | LD_RUNPATH_SEARCH_PATHS = ( 299 | "$(inherited)", 300 | "@executable_path/../Frameworks", 301 | ); 302 | PRODUCT_BUNDLE_IDENTIFIER = hu.purzelbaum.KVC; 303 | PRODUCT_NAME = "$(TARGET_NAME)"; 304 | SWIFT_VERSION = 5.0; 305 | }; 306 | name = Release; 307 | }; 308 | /* End XCBuildConfiguration section */ 309 | 310 | /* Begin XCConfigurationList section */ 311 | 57AFF60A2486B9AE00D121B6 /* Build configuration list for PBXProject "KVC" */ = { 312 | isa = XCConfigurationList; 313 | buildConfigurations = ( 314 | 57AFF61D2486B9B200D121B6 /* Debug */, 315 | 57AFF61E2486B9B200D121B6 /* Release */, 316 | ); 317 | defaultConfigurationIsVisible = 0; 318 | defaultConfigurationName = Release; 319 | }; 320 | 57AFF61F2486B9B200D121B6 /* Build configuration list for PBXNativeTarget "KVC" */ = { 321 | isa = XCConfigurationList; 322 | buildConfigurations = ( 323 | 57AFF6202486B9B200D121B6 /* Debug */, 324 | 57AFF6212486B9B200D121B6 /* Release */, 325 | ); 326 | defaultConfigurationIsVisible = 0; 327 | defaultConfigurationName = Release; 328 | }; 329 | /* End XCConfigurationList section */ 330 | }; 331 | rootObject = 57AFF6072486B9AE00D121B6 /* Project object */; 332 | } 333 | -------------------------------------------------------------------------------- /KVC/KVC.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /KVC/KVC.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /KVC/KVC.xcodeproj/project.xcworkspace/xcuserdata/szabolcs.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/KVC/KVC.xcodeproj/project.xcworkspace/xcuserdata/szabolcs.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /KVC/KVC.xcodeproj/xcuserdata/szabolcs.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | KVC.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /KVC/KVC/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // KVC 4 | // 5 | // Created by Szabolcs Toth on 02/06/2020. 6 | // Copyright © 2020 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject, NSApplicationDelegate { 13 | 14 | 15 | 16 | func applicationDidFinishLaunching(_ aNotification: Notification) { 17 | // Insert code here to initialize your application 18 | } 19 | 20 | func applicationWillTerminate(_ aNotification: Notification) { 21 | // Insert code here to tear down your application 22 | } 23 | 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /KVC/KVC/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "scale" : "1x", 6 | "size" : "16x16" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "scale" : "2x", 11 | "size" : "16x16" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "scale" : "1x", 16 | "size" : "32x32" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "scale" : "2x", 21 | "size" : "32x32" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "scale" : "1x", 26 | "size" : "128x128" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "scale" : "2x", 31 | "size" : "128x128" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "scale" : "1x", 36 | "size" : "256x256" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "scale" : "2x", 41 | "size" : "256x256" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "scale" : "1x", 46 | "size" : "512x512" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "scale" : "2x", 51 | "size" : "512x512" 52 | } 53 | ], 54 | "info" : { 55 | "author" : "xcode", 56 | "version" : 1 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /KVC/KVC/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /KVC/KVC/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2020 purzelbaum.hu. All rights reserved. 27 | NSMainStoryboardFile 28 | Main 29 | NSPrincipalClass 30 | NSApplication 31 | NSSupportsAutomaticTermination 32 | 33 | NSSupportsSuddenTermination 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /KVC/KVC/KVC.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /KVC/KVC/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // KVC 4 | // 5 | // Created by Szabolcs Toth on 02/06/2020. 6 | // Copyright © 2020 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class ViewController: NSViewController { 12 | 13 | @objc dynamic var temperature: Int = 68 14 | @objc dynamic var isItOn: Bool = true 15 | 16 | override func viewDidLoad() { 17 | super.viewDidLoad() 18 | 19 | // Do any additional setup after loading the view. 20 | } 21 | 22 | override var representedObject: Any? { 23 | didSet { 24 | // Update the view, if already loaded. 25 | } 26 | } 27 | 28 | @IBAction func coolerPressed(_ sender: Any) { 29 | temperature -= 1 30 | } 31 | 32 | @IBAction func warmerPressed(_ sender: Any) { 33 | temperature += 1 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /KVC/ReadMe.md: -------------------------------------------------------------------------------- 1 | ## KVC, KVO and Bindings 2 | 3 | ![Thermostat](Thermostat.png) 4 | 5 | This tutorial is based on [Aaron Hillegass - Cocoa Programming for OS X: The Big Nerd Ranch Guide](https://www.oreilly.com/library/view/cocoa-programming-for/9780134077130/) 6 | 7 | The original tutorial was written for Xcode 6.3 and Swift 1.2. I have updated for Xcode 11.5 and Swift 5.2. All credits must go to the original authors. 8 | 9 | Tutorial can be found [here](https://kicsipixel.github.io/2020/kvc/) -------------------------------------------------------------------------------- /KVC/Thermostat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/KVC/Thermostat.png -------------------------------------------------------------------------------- /MapKitmacOS/MapKit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/MapKitmacOS/MapKit.png -------------------------------------------------------------------------------- /MapKitmacOS/MapKitmacOS.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 5739D76E2371B55E001D5541 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5739D76D2371B55E001D5541 /* AppDelegate.swift */; }; 11 | 5739D7702371B55E001D5541 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5739D76F2371B55E001D5541 /* ViewController.swift */; }; 12 | 5739D7722371B560001D5541 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5739D7712371B560001D5541 /* Assets.xcassets */; }; 13 | 5739D7752371B560001D5541 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5739D7732371B560001D5541 /* Main.storyboard */; }; 14 | /* End PBXBuildFile section */ 15 | 16 | /* Begin PBXFileReference section */ 17 | 5739D76A2371B55E001D5541 /* MapKitmacOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MapKitmacOS.app; sourceTree = BUILT_PRODUCTS_DIR; }; 18 | 5739D76D2371B55E001D5541 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 19 | 5739D76F2371B55E001D5541 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 20 | 5739D7712371B560001D5541 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 21 | 5739D7742371B560001D5541 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 22 | 5739D7762371B560001D5541 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 23 | 5739D7772371B560001D5541 /* MapKitmacOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MapKitmacOS.entitlements; sourceTree = ""; }; 24 | /* End PBXFileReference section */ 25 | 26 | /* Begin PBXFrameworksBuildPhase section */ 27 | 5739D7672371B55E001D5541 /* Frameworks */ = { 28 | isa = PBXFrameworksBuildPhase; 29 | buildActionMask = 2147483647; 30 | files = ( 31 | ); 32 | runOnlyForDeploymentPostprocessing = 0; 33 | }; 34 | /* End PBXFrameworksBuildPhase section */ 35 | 36 | /* Begin PBXGroup section */ 37 | 5739D7612371B55E001D5541 = { 38 | isa = PBXGroup; 39 | children = ( 40 | 5739D76C2371B55E001D5541 /* MapKitmacOS */, 41 | 5739D76B2371B55E001D5541 /* Products */, 42 | ); 43 | sourceTree = ""; 44 | }; 45 | 5739D76B2371B55E001D5541 /* Products */ = { 46 | isa = PBXGroup; 47 | children = ( 48 | 5739D76A2371B55E001D5541 /* MapKitmacOS.app */, 49 | ); 50 | name = Products; 51 | sourceTree = ""; 52 | }; 53 | 5739D76C2371B55E001D5541 /* MapKitmacOS */ = { 54 | isa = PBXGroup; 55 | children = ( 56 | 5739D76D2371B55E001D5541 /* AppDelegate.swift */, 57 | 5739D76F2371B55E001D5541 /* ViewController.swift */, 58 | 5739D7712371B560001D5541 /* Assets.xcassets */, 59 | 5739D7732371B560001D5541 /* Main.storyboard */, 60 | 5739D7762371B560001D5541 /* Info.plist */, 61 | 5739D7772371B560001D5541 /* MapKitmacOS.entitlements */, 62 | ); 63 | path = MapKitmacOS; 64 | sourceTree = ""; 65 | }; 66 | /* End PBXGroup section */ 67 | 68 | /* Begin PBXNativeTarget section */ 69 | 5739D7692371B55E001D5541 /* MapKitmacOS */ = { 70 | isa = PBXNativeTarget; 71 | buildConfigurationList = 5739D77A2371B560001D5541 /* Build configuration list for PBXNativeTarget "MapKitmacOS" */; 72 | buildPhases = ( 73 | 5739D7662371B55E001D5541 /* Sources */, 74 | 5739D7672371B55E001D5541 /* Frameworks */, 75 | 5739D7682371B55E001D5541 /* Resources */, 76 | ); 77 | buildRules = ( 78 | ); 79 | dependencies = ( 80 | ); 81 | name = MapKitmacOS; 82 | productName = MapKitmacOS; 83 | productReference = 5739D76A2371B55E001D5541 /* MapKitmacOS.app */; 84 | productType = "com.apple.product-type.application"; 85 | }; 86 | /* End PBXNativeTarget section */ 87 | 88 | /* Begin PBXProject section */ 89 | 5739D7622371B55E001D5541 /* Project object */ = { 90 | isa = PBXProject; 91 | attributes = { 92 | LastSwiftUpdateCheck = 1120; 93 | LastUpgradeCheck = 1120; 94 | ORGANIZATIONNAME = purzelbaum.hu; 95 | TargetAttributes = { 96 | 5739D7692371B55E001D5541 = { 97 | CreatedOnToolsVersion = 11.2; 98 | }; 99 | }; 100 | }; 101 | buildConfigurationList = 5739D7652371B55E001D5541 /* Build configuration list for PBXProject "MapKitmacOS" */; 102 | compatibilityVersion = "Xcode 9.3"; 103 | developmentRegion = en; 104 | hasScannedForEncodings = 0; 105 | knownRegions = ( 106 | en, 107 | Base, 108 | ); 109 | mainGroup = 5739D7612371B55E001D5541; 110 | productRefGroup = 5739D76B2371B55E001D5541 /* Products */; 111 | projectDirPath = ""; 112 | projectRoot = ""; 113 | targets = ( 114 | 5739D7692371B55E001D5541 /* MapKitmacOS */, 115 | ); 116 | }; 117 | /* End PBXProject section */ 118 | 119 | /* Begin PBXResourcesBuildPhase section */ 120 | 5739D7682371B55E001D5541 /* Resources */ = { 121 | isa = PBXResourcesBuildPhase; 122 | buildActionMask = 2147483647; 123 | files = ( 124 | 5739D7722371B560001D5541 /* Assets.xcassets in Resources */, 125 | 5739D7752371B560001D5541 /* Main.storyboard in Resources */, 126 | ); 127 | runOnlyForDeploymentPostprocessing = 0; 128 | }; 129 | /* End PBXResourcesBuildPhase section */ 130 | 131 | /* Begin PBXSourcesBuildPhase section */ 132 | 5739D7662371B55E001D5541 /* Sources */ = { 133 | isa = PBXSourcesBuildPhase; 134 | buildActionMask = 2147483647; 135 | files = ( 136 | 5739D7702371B55E001D5541 /* ViewController.swift in Sources */, 137 | 5739D76E2371B55E001D5541 /* AppDelegate.swift in Sources */, 138 | ); 139 | runOnlyForDeploymentPostprocessing = 0; 140 | }; 141 | /* End PBXSourcesBuildPhase section */ 142 | 143 | /* Begin PBXVariantGroup section */ 144 | 5739D7732371B560001D5541 /* Main.storyboard */ = { 145 | isa = PBXVariantGroup; 146 | children = ( 147 | 5739D7742371B560001D5541 /* Base */, 148 | ); 149 | name = Main.storyboard; 150 | sourceTree = ""; 151 | }; 152 | /* End PBXVariantGroup section */ 153 | 154 | /* Begin XCBuildConfiguration section */ 155 | 5739D7782371B560001D5541 /* Debug */ = { 156 | isa = XCBuildConfiguration; 157 | buildSettings = { 158 | ALWAYS_SEARCH_USER_PATHS = NO; 159 | CLANG_ANALYZER_NONNULL = YES; 160 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 161 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 162 | CLANG_CXX_LIBRARY = "libc++"; 163 | CLANG_ENABLE_MODULES = YES; 164 | CLANG_ENABLE_OBJC_ARC = YES; 165 | CLANG_ENABLE_OBJC_WEAK = YES; 166 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 167 | CLANG_WARN_BOOL_CONVERSION = YES; 168 | CLANG_WARN_COMMA = YES; 169 | CLANG_WARN_CONSTANT_CONVERSION = YES; 170 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 171 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 172 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 173 | CLANG_WARN_EMPTY_BODY = YES; 174 | CLANG_WARN_ENUM_CONVERSION = YES; 175 | CLANG_WARN_INFINITE_RECURSION = YES; 176 | CLANG_WARN_INT_CONVERSION = YES; 177 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 178 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 179 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 180 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 181 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 182 | CLANG_WARN_STRICT_PROTOTYPES = YES; 183 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 184 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 185 | CLANG_WARN_UNREACHABLE_CODE = YES; 186 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 187 | COPY_PHASE_STRIP = NO; 188 | DEBUG_INFORMATION_FORMAT = dwarf; 189 | ENABLE_STRICT_OBJC_MSGSEND = YES; 190 | ENABLE_TESTABILITY = YES; 191 | GCC_C_LANGUAGE_STANDARD = gnu11; 192 | GCC_DYNAMIC_NO_PIC = NO; 193 | GCC_NO_COMMON_BLOCKS = YES; 194 | GCC_OPTIMIZATION_LEVEL = 0; 195 | GCC_PREPROCESSOR_DEFINITIONS = ( 196 | "DEBUG=1", 197 | "$(inherited)", 198 | ); 199 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 200 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 201 | GCC_WARN_UNDECLARED_SELECTOR = YES; 202 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 203 | GCC_WARN_UNUSED_FUNCTION = YES; 204 | GCC_WARN_UNUSED_VARIABLE = YES; 205 | MACOSX_DEPLOYMENT_TARGET = 10.15; 206 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 207 | MTL_FAST_MATH = YES; 208 | ONLY_ACTIVE_ARCH = YES; 209 | SDKROOT = macosx; 210 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 211 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 212 | }; 213 | name = Debug; 214 | }; 215 | 5739D7792371B560001D5541 /* Release */ = { 216 | isa = XCBuildConfiguration; 217 | buildSettings = { 218 | ALWAYS_SEARCH_USER_PATHS = NO; 219 | CLANG_ANALYZER_NONNULL = YES; 220 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 221 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 222 | CLANG_CXX_LIBRARY = "libc++"; 223 | CLANG_ENABLE_MODULES = YES; 224 | CLANG_ENABLE_OBJC_ARC = YES; 225 | CLANG_ENABLE_OBJC_WEAK = YES; 226 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 227 | CLANG_WARN_BOOL_CONVERSION = YES; 228 | CLANG_WARN_COMMA = YES; 229 | CLANG_WARN_CONSTANT_CONVERSION = YES; 230 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 231 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 232 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 233 | CLANG_WARN_EMPTY_BODY = YES; 234 | CLANG_WARN_ENUM_CONVERSION = YES; 235 | CLANG_WARN_INFINITE_RECURSION = YES; 236 | CLANG_WARN_INT_CONVERSION = YES; 237 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 238 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 239 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 240 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 241 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 242 | CLANG_WARN_STRICT_PROTOTYPES = YES; 243 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 244 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 245 | CLANG_WARN_UNREACHABLE_CODE = YES; 246 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 247 | COPY_PHASE_STRIP = NO; 248 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 249 | ENABLE_NS_ASSERTIONS = NO; 250 | ENABLE_STRICT_OBJC_MSGSEND = YES; 251 | GCC_C_LANGUAGE_STANDARD = gnu11; 252 | GCC_NO_COMMON_BLOCKS = YES; 253 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 254 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 255 | GCC_WARN_UNDECLARED_SELECTOR = YES; 256 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 257 | GCC_WARN_UNUSED_FUNCTION = YES; 258 | GCC_WARN_UNUSED_VARIABLE = YES; 259 | MACOSX_DEPLOYMENT_TARGET = 10.15; 260 | MTL_ENABLE_DEBUG_INFO = NO; 261 | MTL_FAST_MATH = YES; 262 | SDKROOT = macosx; 263 | SWIFT_COMPILATION_MODE = wholemodule; 264 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 265 | }; 266 | name = Release; 267 | }; 268 | 5739D77B2371B560001D5541 /* Debug */ = { 269 | isa = XCBuildConfiguration; 270 | buildSettings = { 271 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 272 | CODE_SIGN_ENTITLEMENTS = MapKitmacOS/MapKitmacOS.entitlements; 273 | CODE_SIGN_STYLE = Automatic; 274 | COMBINE_HIDPI_IMAGES = YES; 275 | DEVELOPMENT_TEAM = 358WHQF94W; 276 | ENABLE_HARDENED_RUNTIME = YES; 277 | INFOPLIST_FILE = MapKitmacOS/Info.plist; 278 | LD_RUNPATH_SEARCH_PATHS = ( 279 | "$(inherited)", 280 | "@executable_path/../Frameworks", 281 | ); 282 | PRODUCT_BUNDLE_IDENTIFIER = hu.purzelbaum.MapKitmacOS; 283 | PRODUCT_NAME = "$(TARGET_NAME)"; 284 | SWIFT_VERSION = 5.0; 285 | }; 286 | name = Debug; 287 | }; 288 | 5739D77C2371B560001D5541 /* Release */ = { 289 | isa = XCBuildConfiguration; 290 | buildSettings = { 291 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 292 | CODE_SIGN_ENTITLEMENTS = MapKitmacOS/MapKitmacOS.entitlements; 293 | CODE_SIGN_STYLE = Automatic; 294 | COMBINE_HIDPI_IMAGES = YES; 295 | DEVELOPMENT_TEAM = 358WHQF94W; 296 | ENABLE_HARDENED_RUNTIME = YES; 297 | INFOPLIST_FILE = MapKitmacOS/Info.plist; 298 | LD_RUNPATH_SEARCH_PATHS = ( 299 | "$(inherited)", 300 | "@executable_path/../Frameworks", 301 | ); 302 | PRODUCT_BUNDLE_IDENTIFIER = hu.purzelbaum.MapKitmacOS; 303 | PRODUCT_NAME = "$(TARGET_NAME)"; 304 | SWIFT_VERSION = 5.0; 305 | }; 306 | name = Release; 307 | }; 308 | /* End XCBuildConfiguration section */ 309 | 310 | /* Begin XCConfigurationList section */ 311 | 5739D7652371B55E001D5541 /* Build configuration list for PBXProject "MapKitmacOS" */ = { 312 | isa = XCConfigurationList; 313 | buildConfigurations = ( 314 | 5739D7782371B560001D5541 /* Debug */, 315 | 5739D7792371B560001D5541 /* Release */, 316 | ); 317 | defaultConfigurationIsVisible = 0; 318 | defaultConfigurationName = Release; 319 | }; 320 | 5739D77A2371B560001D5541 /* Build configuration list for PBXNativeTarget "MapKitmacOS" */ = { 321 | isa = XCConfigurationList; 322 | buildConfigurations = ( 323 | 5739D77B2371B560001D5541 /* Debug */, 324 | 5739D77C2371B560001D5541 /* Release */, 325 | ); 326 | defaultConfigurationIsVisible = 0; 327 | defaultConfigurationName = Release; 328 | }; 329 | /* End XCConfigurationList section */ 330 | }; 331 | rootObject = 5739D7622371B55E001D5541 /* Project object */; 332 | } 333 | -------------------------------------------------------------------------------- /MapKitmacOS/MapKitmacOS.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /MapKitmacOS/MapKitmacOS.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /MapKitmacOS/MapKitmacOS.xcodeproj/project.xcworkspace/xcuserdata/szabolcs.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/MapKitmacOS/MapKitmacOS.xcodeproj/project.xcworkspace/xcuserdata/szabolcs.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /MapKitmacOS/MapKitmacOS.xcodeproj/xcuserdata/szabolcs.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | MapKitmacOS.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /MapKitmacOS/MapKitmacOS/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // MapKitmacOS 4 | // 5 | // Created by Szabolcs Toth on 05/11/2019. 6 | // Copyright © 2019 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject, NSApplicationDelegate { 13 | 14 | 15 | 16 | func applicationDidFinishLaunching(_ aNotification: Notification) { 17 | // Insert code here to initialize your application 18 | } 19 | 20 | func applicationWillTerminate(_ aNotification: Notification) { 21 | // Insert code here to tear down your application 22 | } 23 | 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /MapKitmacOS/MapKitmacOS/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /MapKitmacOS/MapKitmacOS/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /MapKitmacOS/MapKitmacOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2019 purzelbaum.hu. All rights reserved. 27 | NSMainStoryboardFile 28 | Main 29 | NSPrincipalClass 30 | NSApplication 31 | NSSupportsAutomaticTermination 32 | 33 | NSSupportsSuddenTermination 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /MapKitmacOS/MapKitmacOS/MapKitmacOS.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | com.apple.security.network.client 10 | 11 | com.apple.security.network.server 12 | 13 | com.apple.security.personal-information.location 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /MapKitmacOS/MapKitmacOS/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // MapKitmacOS 4 | // 5 | // Created by Szabolcs Toth on 05/11/2019. 6 | // Copyright © 2019 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import MapKit 11 | import CoreLocation 12 | 13 | class ViewController: NSViewController { 14 | 15 | @IBOutlet var mapView: MKMapView! 16 | let locationManager = CLLocationManager() 17 | let regionMeter: Double = 10000 18 | 19 | override func viewDidLoad() { 20 | super.viewDidLoad() 21 | checkLocationServices() 22 | } 23 | 24 | func setupLocationManager() { 25 | locationManager.delegate = self 26 | locationManager.desiredAccuracy = kCLLocationAccuracyBest 27 | } 28 | 29 | func checkLocationServices() { 30 | if CLLocationManager.locationServicesEnabled() { 31 | setupLocationManager() 32 | checkLocationAutherization() 33 | } else { 34 | showAlert(issue: "not enabled") 35 | } 36 | } 37 | 38 | func centerViewOnUserLocation() { 39 | if let location = locationManager.location?.coordinate { 40 | let region = MKCoordinateRegion.init(center: location, latitudinalMeters: regionMeter, longitudinalMeters: regionMeter) 41 | mapView.setRegion(region, animated: true) 42 | } 43 | } 44 | 45 | func checkLocationAutherization() { 46 | switch CLLocationManager.authorizationStatus() { 47 | case .authorized: 48 | mapView.showsUserLocation = true 49 | centerViewOnUserLocation() 50 | locationManager.startUpdatingLocation() 51 | break 52 | case .denied: 53 | showAlert(issue: "denied") 54 | break 55 | case .notDetermined: 56 | locationManager.requestAlwaysAuthorization() 57 | break 58 | case .restricted: 59 | showAlert(issue: "restricted") 60 | break 61 | case .authorizedAlways: 62 | break 63 | @unknown default: 64 | break 65 | } 66 | } 67 | 68 | func showAlert(issue: String) { 69 | let alert = NSAlert() 70 | 71 | switch issue { 72 | case "not enabled": 73 | alert.messageText = "Enable Location Services" 74 | alert.informativeText = "Location services are not enabled. Please, check it in your Sytem Preferences." 75 | _ = alert.runModal() 76 | case "denied": 77 | alert.messageText = "Enable Location Services" 78 | alert.informativeText = "Location services are denied. Please, check it in your Sytem Preferences." 79 | _ = alert.runModal() 80 | default: 81 | alert.messageText = "Enable Location Services" 82 | alert.informativeText = "Location services are restricted. Please, check it in your Sytem Preferences." 83 | _ = alert.runModal() 84 | } 85 | } 86 | 87 | 88 | } 89 | 90 | extension ViewController: CLLocationManagerDelegate { 91 | func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { 92 | guard let location = locations.last else { return } 93 | let center = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude) 94 | let region = MKCoordinateRegion.init(center: center, latitudinalMeters: regionMeter, longitudinalMeters: regionMeter) 95 | mapView.setRegion(region, animated: true) 96 | } 97 | 98 | func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { 99 | checkLocationAutherization() 100 | } 101 | } 102 | 103 | -------------------------------------------------------------------------------- /MapKitmacOS/ReadMe.md: -------------------------------------------------------------------------------- 1 | ## MapKit on macOS 2 | 3 | ![MapKit](MapKit.png) 4 | 5 | I followed this tutorial on [youtube](https://www.youtube.com/watch?v=WPpaAy73nJc) by Sean Allen and surprisingly no big differences comparing to iOS version. -------------------------------------------------------------------------------- /NSCollectionView/NSCollectionView.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/NSCollectionView/NSCollectionView.png -------------------------------------------------------------------------------- /NSCollectionView/NSCollectionView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /NSCollectionView/NSCollectionView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /NSCollectionView/NSCollectionView.xcodeproj/project.xcworkspace/xcuserdata/szabolcs.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/NSCollectionView/NSCollectionView.xcodeproj/project.xcworkspace/xcuserdata/szabolcs.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /NSCollectionView/NSCollectionView.xcodeproj/xcuserdata/szabolcs.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | NSCollectionView.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /NSCollectionView/NSCollectionView/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // NSCollectionView 4 | // 5 | // Created by Szabolcs Toth on 06/01/2020. 6 | // Copyright © 2020 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject, NSApplicationDelegate { 13 | 14 | 15 | 16 | func applicationDidFinishLaunching(_ aNotification: Notification) { 17 | // Insert code here to initialize your application 18 | } 19 | 20 | func applicationWillTerminate(_ aNotification: Notification) { 21 | // Insert code here to tear down your application 22 | } 23 | 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /NSCollectionView/NSCollectionView/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /NSCollectionView/NSCollectionView/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /NSCollectionView/NSCollectionView/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2020 purzelbaum.hu. All rights reserved. 27 | NSMainStoryboardFile 28 | Main 29 | NSPrincipalClass 30 | NSApplication 31 | NSSupportsAutomaticTermination 32 | 33 | NSSupportsSuddenTermination 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /NSCollectionView/NSCollectionView/Item.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Item.swift 3 | // NSCollectionView 4 | // 5 | // Created by Szabolcs Toth on 06/01/2020. 6 | // Copyright © 2020 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class Item: NSCollectionViewItem { 12 | 13 | @IBOutlet var letterLabel: NSTextField! 14 | 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | // Do view setup here. 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /NSCollectionView/NSCollectionView/Item.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /NSCollectionView/NSCollectionView/NSCollectionView.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /NSCollectionView/NSCollectionView/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // NSCollectionView 4 | // 5 | // Created by Szabolcs Toth on 06/01/2020. 6 | // Copyright © 2020 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class ViewController: NSViewController { 12 | 13 | @IBOutlet var collectionView: NSCollectionView! 14 | 15 | let items = ["Aarne", 16 | "Bertta", 17 | "Celsius", 18 | "Daavid", 19 | "Eemeli", 20 | "Faarao", 21 | "Gideon", 22 | "Heikki", 23 | "Iivari", 24 | "Jussi", 25 | "Kalle", 26 | "Lauri", 27 | "Matti", 28 | "Niilo", 29 | "Otto", 30 | "Paavo", 31 | "kuu", 32 | "Risto", 33 | "Sakari", 34 | "Tyyne", 35 | "Urho", 36 | "Vihtori", 37 | "Viski", 38 | "äksä", 39 | "Yrjö", 40 | "zeta", 41 | "Åke", 42 | "äiti", 43 | "öljy" ] 44 | 45 | let backgroundColor = NSColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.35).cgColor 46 | 47 | override func viewDidLoad() { 48 | super.viewDidLoad() 49 | } 50 | 51 | override var representedObject: Any? { 52 | didSet { 53 | // Update the view, if already loaded. 54 | } 55 | } 56 | 57 | 58 | } 59 | 60 | extension ViewController: NSCollectionViewDataSource, NSCollectionViewDelegate { 61 | func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int { 62 | return self.items.count 63 | } 64 | 65 | func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem { 66 | let item = collectionView.makeItem(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "Item"), for: indexPath) 67 | 68 | guard let collectionViewItem = item as? Item else { return item } 69 | 70 | collectionViewItem.letterLabel.stringValue = self.items[indexPath.item] 71 | 72 | collectionViewItem.view.wantsLayer = true 73 | collectionViewItem.view.layer?.backgroundColor = backgroundColor 74 | 75 | return item 76 | } 77 | 78 | 79 | } 80 | -------------------------------------------------------------------------------- /NSCollectionView/ReadMe.md: -------------------------------------------------------------------------------- 1 | ## NSCollectionView Sample 2 | 3 | ![NSCollectionView](NSCollectionView.png) 4 | -------------------------------------------------------------------------------- /NSOutlineView/NSOutlineView.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/NSOutlineView/NSOutlineView.png -------------------------------------------------------------------------------- /NSOutlineView/NSOutlineView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /NSOutlineView/NSOutlineView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /NSOutlineView/NSOutlineView.xcodeproj/project.xcworkspace/xcuserdata/szabolcs.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/NSOutlineView/NSOutlineView.xcodeproj/project.xcworkspace/xcuserdata/szabolcs.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /NSOutlineView/NSOutlineView.xcodeproj/xcuserdata/szabolcs.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /NSOutlineView/NSOutlineView.xcodeproj/xcuserdata/szabolcs.xcuserdatad/xcschemes/NSOutlineView.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /NSOutlineView/NSOutlineView.xcodeproj/xcuserdata/szabolcs.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | NSOutlineView.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 57D3471D1EF1819D004493DD 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /NSOutlineView/NSOutlineView/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // NSOutlineView 4 | // 5 | // Created by Szabolcs Toth on 6/14/17. 6 | // Copyright © 2017 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject, NSApplicationDelegate { 13 | 14 | 15 | 16 | func applicationDidFinishLaunching(_ aNotification: Notification) { 17 | // Insert code here to initialize your application 18 | } 19 | 20 | func applicationWillTerminate(_ aNotification: Notification) { 21 | // Insert code here to tear down your application 22 | } 23 | 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /NSOutlineView/NSOutlineView/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /NSOutlineView/NSOutlineView/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2017 purzelbaum.hu. All rights reserved. 27 | NSMainStoryboardFile 28 | Main 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /NSOutlineView/NSOutlineView/Person.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Person.swift 3 | // NSOutlineView 4 | // 5 | // Created by Szabolcs Toth on 6/14/17. 6 | // Copyright © 2017 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class Person: NSObject { 12 | let name: String 13 | 14 | init(name: String) { 15 | self.name = name 16 | } 17 | } 18 | 19 | class Family: NSObject { 20 | let familyName: String 21 | var member: [Person] = [] 22 | 23 | init(familyName: String) { 24 | self.familyName = familyName 25 | } 26 | } 27 | 28 | class Country: NSObject { 29 | let country: String 30 | var families: [Family] = [] 31 | 32 | init(country: String) { 33 | self.country = country 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /NSOutlineView/NSOutlineView/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // NSOutlineView 4 | // 5 | // Created by Szabolcs Toth on 6/14/17. 6 | // Copyright © 2017 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class ViewController: NSViewController, NSOutlineViewDelegate, NSOutlineViewDataSource { 12 | 13 | 14 | @IBOutlet var outlineView: NSOutlineView! 15 | 16 | let country1 = Country(country: "Norway") 17 | let country2 = Country(country: "England") 18 | 19 | override func viewDidLoad() { 20 | super.viewDidLoad() 21 | 22 | let person1 = Person(name: "Ragnar") 23 | let person2 = Person(name: "Rollo") 24 | let person3 = Person(name: "Bjorn") 25 | let person4 = Person(name: "Siggy") 26 | let person5 = Person(name: "Henry VII") 27 | let person6 = Person(name: "Henry VIII") 28 | 29 | let family1 = Family(familyName: "Lothbrok") 30 | let family2 = Family(familyName: "Haraldson") 31 | let family3 = Family(familyName: "Tudor") 32 | 33 | family1.member.append(person1) 34 | family1.member.append(person2) 35 | family1.member.append(person3) 36 | 37 | family2.member.append(person4) 38 | 39 | family3.member.append(person5) 40 | family3.member.append(person6) 41 | 42 | country1.families.append(family1) 43 | country1.families.append(family2) 44 | 45 | country2.families.append(family3) 46 | 47 | // Allow HeaderCell to move up 48 | // outlineView.floatsGroupRows = false 49 | 50 | } 51 | 52 | func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int { 53 | if let item: Any = item { 54 | switch item { 55 | case let country as Country: 56 | return country.families.count 57 | case let family as Family: 58 | return family.member.count 59 | default: 60 | return 0 61 | } 62 | } else { 63 | return 2 64 | } 65 | } 66 | 67 | func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any { 68 | if let item: Any = item { 69 | switch item { 70 | case let country as Country: 71 | return country.families[index] 72 | case let family as Family: 73 | return family.member[index] 74 | default: 75 | return self 76 | } 77 | } else { 78 | switch index { 79 | case 0: 80 | return country1 81 | default: 82 | return country2 83 | } 84 | } 85 | } 86 | 87 | func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: Any) -> Bool { 88 | switch item { 89 | case let country as Country: 90 | return (country.families.count > 0) ? true : false 91 | case let family as Family: 92 | return (family.member.count > 0) ? true : false 93 | default: 94 | return false 95 | } 96 | } 97 | 98 | /* 99 | func outlineView(_ outlineView: NSOutlineView, isGroupItem item: Any) -> Bool { 100 | switch item { 101 | case let country as Country: 102 | return true 103 | case let family as Family: 104 | return true 105 | default: 106 | return false 107 | } 108 | } 109 | */ 110 | 111 | func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? { 112 | switch item { 113 | case let country as Country: 114 | let view = outlineView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "HeaderCell"), owner: self) as! NSTableCellView 115 | if let textField = view.textField { 116 | textField.stringValue = country.country 117 | } 118 | return view 119 | 120 | case let family as Family: 121 | let view = outlineView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "DataCell"), owner: self) as! NSTableCellView 122 | if let textField = view.textField { 123 | textField.stringValue = family.familyName 124 | } 125 | return view 126 | 127 | case let person as Person: 128 | let view = outlineView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "DataCell"), owner: self) as! NSTableCellView 129 | if let textField = view.textField { 130 | textField.stringValue = person.name 131 | } 132 | return view 133 | 134 | default: 135 | return nil 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /NSOutlineView/ReadMe.md: -------------------------------------------------------------------------------- 1 | ## NSOutlineView Sample 2 | 3 | ![NSOutlineView](NSOutlineView.png) -------------------------------------------------------------------------------- /NSTabView/NSTabView.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/NSTabView/NSTabView.png -------------------------------------------------------------------------------- /NSTabView/NSTabView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /NSTabView/NSTabView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /NSTabView/NSTabView.xcodeproj/project.xcworkspace/xcuserdata/szabolcs.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/NSTabView/NSTabView.xcodeproj/project.xcworkspace/xcuserdata/szabolcs.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /NSTabView/NSTabView.xcodeproj/xcuserdata/szabolcs.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | NSTabView.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /NSTabView/NSTabView/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // NSTabView 4 | // 5 | // Created by Szabolcs Toth on 11/19/18. 6 | // Copyright © 2018 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject, NSApplicationDelegate { 13 | 14 | 15 | 16 | func applicationDidFinishLaunching(_ aNotification: Notification) { 17 | // Insert code here to initialize your application 18 | } 19 | 20 | func applicationWillTerminate(_ aNotification: Notification) { 21 | // Insert code here to tear down your application 22 | } 23 | 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /NSTabView/NSTabView/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /NSTabView/NSTabView/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /NSTabView/NSTabView/Assets.xcassets/line _chart.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "line _chart@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /NSTabView/NSTabView/Assets.xcassets/line _chart.imageset/line _chart@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/NSTabView/NSTabView/Assets.xcassets/line _chart.imageset/line _chart@2x.png -------------------------------------------------------------------------------- /NSTabView/NSTabView/Assets.xcassets/line _chart_XXL.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "line _chart_XXL@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /NSTabView/NSTabView/Assets.xcassets/line _chart_XXL.imageset/line _chart_XXL@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/NSTabView/NSTabView/Assets.xcassets/line _chart_XXL.imageset/line _chart_XXL@2x.png -------------------------------------------------------------------------------- /NSTabView/NSTabView/Assets.xcassets/pie_chart.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "pie_chart@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /NSTabView/NSTabView/Assets.xcassets/pie_chart.imageset/pie_chart@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/NSTabView/NSTabView/Assets.xcassets/pie_chart.imageset/pie_chart@2x.png -------------------------------------------------------------------------------- /NSTabView/NSTabView/Assets.xcassets/pie_chart_XXL.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "pie_chart_XXL@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /NSTabView/NSTabView/Assets.xcassets/pie_chart_XXL.imageset/pie_chart_XXL@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/NSTabView/NSTabView/Assets.xcassets/pie_chart_XXL.imageset/pie_chart_XXL@2x.png -------------------------------------------------------------------------------- /NSTabView/NSTabView/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2018 purzelbaum.hu. All rights reserved. 27 | NSMainStoryboardFile 28 | Main 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /NSTabView/NSTabView/NSTabView.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /NSTabView/NSTabView/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // NSTabView 4 | // 5 | // Created by Szabolcs Toth on 11/19/18. 6 | // Copyright © 2018 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class ViewController: NSViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | // Do any additional setup after loading the view. 17 | } 18 | 19 | override var representedObject: Any? { 20 | didSet { 21 | // Update the view, if already loaded. 22 | } 23 | } 24 | 25 | 26 | } 27 | 28 | -------------------------------------------------------------------------------- /NSTabView/NSTabView/WindowController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WindowController.swift 3 | // NSTabView 4 | // 5 | // Created by Szabolcs Toth on 11/19/18. 6 | // Copyright © 2018 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class WindowController: NSWindowController { 12 | 13 | var tabViewController: NSTabViewController? 14 | 15 | 16 | @IBOutlet var segmentedControl: NSSegmentedControl! 17 | 18 | override func windowDidLoad() { 19 | super.windowDidLoad() 20 | 21 | self.tabViewController = self.window?.contentViewController as? NSTabViewController 22 | 23 | if let window = window { 24 | if let view = window.contentView { 25 | view.wantsLayer = true 26 | window.titleVisibility = .hidden 27 | window.titlebarAppearsTransparent = true 28 | window.backgroundColor = .white 29 | } 30 | } 31 | 32 | } 33 | 34 | @IBAction func segmentedControlSwitched(_ sender: Any) { 35 | let segmentedControl = sender as! NSSegmentedControl 36 | self.tabViewController?.selectedTabViewItemIndex = segmentedControl.selectedSegment 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /NSTabView/ReadMe.md: -------------------------------------------------------------------------------- 1 | ## NSTabView Sample 2 | 3 | ![NSTableView](NSTabView.png) 4 | 5 | The tutorial can be found here: https://kicsipixel.github.io/2018/nstabview/ -------------------------------------------------------------------------------- /NSTableView/NSTableView.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/NSTableView/NSTableView.png -------------------------------------------------------------------------------- /NSTableView/NSTableView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /NSTableView/NSTableView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /NSTableView/NSTableView.xcodeproj/project.xcworkspace/xcuserdata/szabolcs.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/NSTableView/NSTableView.xcodeproj/project.xcworkspace/xcuserdata/szabolcs.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /NSTableView/NSTableView.xcodeproj/xcuserdata/szabolcs.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | NSTableView.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /NSTableView/NSTableView/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // NSTableView 4 | // 5 | // Created by Szabolcs Toth on 11/15/18. 6 | // Copyright © 2018 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject, NSApplicationDelegate { 13 | 14 | 15 | 16 | func applicationDidFinishLaunching(_ aNotification: Notification) { 17 | // Insert code here to initialize your application 18 | } 19 | 20 | func applicationWillTerminate(_ aNotification: Notification) { 21 | // Insert code here to tear down your application 22 | } 23 | 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /NSTableView/NSTableView/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /NSTableView/NSTableView/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /NSTableView/NSTableView/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2018 purzelbaum.hu. All rights reserved. 27 | NSMainStoryboardFile 28 | Main 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /NSTableView/NSTableView/NSTableView.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /NSTableView/NSTableView/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // NSTableView 4 | // 5 | // Created by Szabolcs Toth on 11/15/18. 6 | // Copyright © 2018 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class ViewController: NSViewController { 12 | 13 | @IBOutlet var tableView: NSTableView! 14 | 15 | // our variable 16 | var data: [[String: String]] = [[:]] 17 | 18 | override func viewDidLoad() { 19 | super.viewDidLoad() 20 | 21 | // adding people 22 | data = [ 23 | [ 24 | "firstName" : "Ragnar", 25 | "lastName" : "Lothbrok", 26 | "mobileNumber" : "555-1234" 27 | ], 28 | [ 29 | "firstName" : "Bjorn", 30 | "lastName" : "Lothbrok", 31 | "mobileNumber" : "555-3412" 32 | ], 33 | [ 34 | "firstName" : "Harald", 35 | "lastName" : "Finehair", 36 | "mobileNumber" : "555-4512" 37 | ] 38 | ] 39 | 40 | // reload tableview 41 | tableView.reloadData() 42 | } 43 | 44 | } 45 | 46 | extension ViewController: NSTableViewDataSource, NSTableViewDelegate { 47 | 48 | func numberOfRows(in tableView: NSTableView) -> Int { 49 | return (data.count) 50 | } 51 | 52 | func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { 53 | let person = data[row] 54 | 55 | guard let cell = tableView.makeView(withIdentifier: tableColumn!.identifier, owner: self) as? NSTableCellView else { return nil } 56 | cell.textField?.stringValue = person[tableColumn!.identifier.rawValue]! 57 | 58 | return cell 59 | } 60 | } 61 | 62 | 63 | -------------------------------------------------------------------------------- /NSTableView/ReadMe.md: -------------------------------------------------------------------------------- 1 | ## NSTableView Sample 2 | 3 | ![NSTableView](NSTableView.png) 4 | 5 | The tutorial can be found here: https://kicsipixel.github.io/2018/nstableview/ -------------------------------------------------------------------------------- /NSTableView1/NSTableView.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/NSTableView1/NSTableView.png -------------------------------------------------------------------------------- /NSTableView1/NSTableView1.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /NSTableView1/NSTableView1.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /NSTableView1/NSTableView1.xcodeproj/project.xcworkspace/xcuserdata/szabolcs.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/NSTableView1/NSTableView1.xcodeproj/project.xcworkspace/xcuserdata/szabolcs.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /NSTableView1/NSTableView1.xcodeproj/xcuserdata/szabolcs.xcuserdatad/xcschemes/NSTableView1.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /NSTableView1/NSTableView1.xcodeproj/xcuserdata/szabolcs.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | NSTableView1.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 572F5EF11EF17241007DDA37 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /NSTableView1/NSTableView1/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // NSTableView1 4 | // 5 | // Created by Szabolcs Toth on 6/14/17. 6 | // Copyright © 2017 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject, NSApplicationDelegate { 13 | 14 | 15 | 16 | func applicationDidFinishLaunching(_ aNotification: Notification) { 17 | // Insert code here to initialize your application 18 | } 19 | 20 | func applicationWillTerminate(_ aNotification: Notification) { 21 | // Insert code here to tear down your application 22 | } 23 | 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /NSTableView1/NSTableView1/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /NSTableView1/NSTableView1/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2017 purzelbaum.hu. All rights reserved. 27 | NSMainStoryboardFile 28 | Main 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /NSTableView1/NSTableView1/Person.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Person.swift 3 | // NSTableView1 4 | // 5 | // Created by Szabolcs Toth on 6/14/17. 6 | // Copyright © 2017 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | struct Person { 12 | let firstName: String 13 | let lastName: String 14 | let mobileNumber: String 15 | 16 | } 17 | -------------------------------------------------------------------------------- /NSTableView1/NSTableView1/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // NSTableView1 4 | // 5 | // Created by Szabolcs Toth on 6/14/17. 6 | // Copyright © 2017 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class ViewController: NSViewController { 12 | 13 | @IBOutlet var tableView: NSTableView! 14 | var people: [Person] = [] 15 | 16 | override func viewDidLoad() { 17 | super.viewDidLoad() 18 | 19 | let person1 = Person.init(firstName: "Ragnar", lastName: "Lothbrok", mobileNumber: "555-1234") 20 | let person2 = Person.init(firstName: "Bjorn", lastName: "Lothbrok", mobileNumber: "555-3412") 21 | let person3 = Person.init(firstName: "Harald", lastName: "Finehair", mobileNumber: "555-4512") 22 | people.append(person1) 23 | people.append(person2) 24 | people.append(person3) 25 | } 26 | } 27 | 28 | extension ViewController: NSTableViewDataSource, NSTableViewDelegate { 29 | 30 | func numberOfRows(in tableView: NSTableView) -> Int { 31 | return (people.count) 32 | } 33 | 34 | func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { 35 | let person = people[row] 36 | 37 | guard let cell = tableView.makeView(withIdentifier: tableColumn!.identifier, owner: self) as? NSTableCellView else { return nil } 38 | 39 | if (tableColumn?.identifier)!.rawValue == "firstName" { 40 | cell.textField?.stringValue = person.firstName 41 | } else if (tableColumn?.identifier)!.rawValue == "lastName" { 42 | cell.textField?.stringValue = person.lastName 43 | } else { 44 | cell.textField?.stringValue = person.mobileNumber 45 | } 46 | 47 | return cell 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /NSTableView1/ReadMe.md: -------------------------------------------------------------------------------- 1 | ## NSTableView Sample 2 | 3 | ![NSTableView](NSTableView.png) 4 | 5 | The tutorial can be found here: https://kicsipixel.github.io/2018/nstableview_2/ 6 | -------------------------------------------------------------------------------- /NSTableViewWithLoad/NSTableView1.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /NSTableViewWithLoad/NSTableView1.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /NSTableViewWithLoad/NSTableView1.xcodeproj/project.xcworkspace/xcuserdata/szabolcs.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/NSTableViewWithLoad/NSTableView1.xcodeproj/project.xcworkspace/xcuserdata/szabolcs.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /NSTableViewWithLoad/NSTableView1.xcodeproj/xcuserdata/szabolcs.xcuserdatad/xcschemes/NSTableView1.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /NSTableViewWithLoad/NSTableView1.xcodeproj/xcuserdata/szabolcs.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | NSTableView1.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 572F5EF11EF17241007DDA37 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /NSTableViewWithLoad/NSTableView1/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // NSTableView1 4 | // 5 | // Created by Szabolcs Toth on 6/14/17. 6 | // Copyright © 2017 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject, NSApplicationDelegate { 13 | 14 | 15 | 16 | func applicationDidFinishLaunching(_ aNotification: Notification) { 17 | // Insert code here to initialize your application 18 | } 19 | 20 | func applicationWillTerminate(_ aNotification: Notification) { 21 | // Insert code here to tear down your application 22 | } 23 | 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /NSTableViewWithLoad/NSTableView1/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /NSTableViewWithLoad/NSTableView1/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2017 purzelbaum.hu. All rights reserved. 27 | NSMainStoryboardFile 28 | Main 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /NSTableViewWithLoad/NSTableView1/Person.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Person.swift 3 | // NSTableView1 4 | // 5 | // Created by Szabolcs Toth on 6/14/17. 6 | // Copyright © 2017 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | struct Person: Codable { 12 | let firstName: String 13 | let lastName: String 14 | let mobileNumber: String 15 | } 16 | -------------------------------------------------------------------------------- /NSTableViewWithLoad/NSTableView1/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // NSTableView1 4 | // 5 | // Created by Szabolcs Toth on 6/14/17. 6 | // Copyright © 2017 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class ViewController: NSViewController { 12 | 13 | @IBOutlet var tableView: NSTableView! 14 | var people: [Person] = [] 15 | 16 | override func viewDidLoad() { 17 | super.viewDidLoad() 18 | 19 | let person1 = Person.init(firstName: "Ragnar", lastName: "Lothbrok", mobileNumber: "555-1234") 20 | let person2 = Person.init(firstName: "Bjorn", lastName: "Lothbrok", mobileNumber: "555-3412") 21 | let person3 = Person.init(firstName: "Harald", lastName: "Finehair", mobileNumber: "555-4512") 22 | people.append(person1) 23 | people.append(person2) 24 | people.append(person3) 25 | } 26 | 27 | func prepareDataToSave() -> String { 28 | let jsonEncoder = JSONEncoder() 29 | do { 30 | let jsonData = try jsonEncoder.encode(people) 31 | return String(data: jsonData, encoding: .utf8)! 32 | } catch { 33 | return String(error.localizedDescription) 34 | } 35 | } 36 | 37 | @IBAction func loadButtonPressed(_ sender: Any) { 38 | let dialog = NSOpenPanel() 39 | 40 | dialog.title = "Choose a .table file"; 41 | dialog.showsResizeIndicator = true; 42 | dialog.showsHiddenFiles = false; 43 | dialog.canChooseDirectories = true; 44 | dialog.canCreateDirectories = true; 45 | dialog.allowsMultipleSelection = false; 46 | dialog.allowedFileTypes = ["table"]; 47 | 48 | if (dialog.runModal() == NSApplication.ModalResponse.OK) { 49 | let result = dialog.url 50 | 51 | if (result != nil) { 52 | let jsonData = try! Data(contentsOf: result!) 53 | let decoder = JSONDecoder() 54 | let person = try! decoder.decode([Person].self, from: jsonData) 55 | 56 | people.append(contentsOf: person) 57 | tableView.reloadData() 58 | } else { 59 | // User clicked on "Cancel" 60 | return 61 | } 62 | } 63 | 64 | } 65 | 66 | @IBAction func saveButtonPressed(_ sender: Any) { 67 | let savePanel = NSSavePanel() 68 | let filename = "MyTableData" 69 | savePanel.nameFieldStringValue = "\(filename).table" 70 | savePanel.begin { (result) -> Void in 71 | if result.rawValue == NSApplication.ModalResponse.OK.rawValue { 72 | let exportedFileURL = savePanel.url 73 | let data = self.prepareDataToSave().data(using: String.Encoding.utf8) 74 | 75 | FileManager.default.createFile(atPath: exportedFileURL!.path, contents: data, attributes: nil) 76 | } 77 | } 78 | } 79 | 80 | } 81 | 82 | extension ViewController: NSTableViewDataSource, NSTableViewDelegate { 83 | 84 | func numberOfRows(in tableView: NSTableView) -> Int { 85 | return (people.count) 86 | } 87 | 88 | func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { 89 | let person = people[row] 90 | 91 | guard let cell = tableView.makeView(withIdentifier: tableColumn!.identifier, owner: self) as? NSTableCellView else { return nil } 92 | 93 | if (tableColumn?.identifier)!.rawValue == "firstName" { 94 | cell.textField?.stringValue = person.firstName 95 | } else if (tableColumn?.identifier)!.rawValue == "lastName" { 96 | cell.textField?.stringValue = person.lastName 97 | } else { 98 | cell.textField?.stringValue = person.mobileNumber 99 | } 100 | 101 | return cell 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /NSTableViewWithLoad/ReadMe.md: -------------------------------------------------------------------------------- 1 | ## NSTableView Sample 2 | 3 | An NSTableView which can save and load data. 4 | -------------------------------------------------------------------------------- /PaintCode/PaintCode.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /PaintCode/PaintCode.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /PaintCode/PaintCode.xcodeproj/project.xcworkspace/xcuserdata/szabolcs.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/PaintCode/PaintCode.xcodeproj/project.xcworkspace/xcuserdata/szabolcs.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /PaintCode/PaintCode.xcodeproj/xcuserdata/szabolcs.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /PaintCode/PaintCode.xcodeproj/xcuserdata/szabolcs.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | PaintCode.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /PaintCode/PaintCode/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // PaintCode 4 | // 5 | // Created by Szabolcs Toth on 11/18/18. 6 | // Copyright © 2018 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject, NSApplicationDelegate { 13 | 14 | 15 | 16 | func applicationDidFinishLaunching(_ aNotification: Notification) { 17 | // Insert code here to initialize your application 18 | } 19 | 20 | func applicationWillTerminate(_ aNotification: Notification) { 21 | // Insert code here to tear down your application 22 | } 23 | 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /PaintCode/PaintCode/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /PaintCode/PaintCode/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /PaintCode/PaintCode/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2018 purzelbaum.hu. All rights reserved. 27 | NSMainStoryboardFile 28 | Main 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /PaintCode/PaintCode/Origami.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Origami.swift 3 | // PaintCode 4 | // 5 | // Created by Szabolcs Toth on 11/18/18. 6 | // Copyright © 2018 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class Origami: NSImageView { 12 | 13 | override func draw(_ dirtyRect: NSRect) { 14 | super.draw(dirtyRect) 15 | 16 | PaintCode.drawOrigami() 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /PaintCode/PaintCode/PaintCode.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /PaintCode/PaintCode/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // PaintCode 4 | // 5 | // Created by Szabolcs Toth on 11/18/18. 6 | // Copyright © 2018 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class ViewController: NSViewController { 12 | 13 | @IBOutlet var origamiImage: NSImageView! 14 | @IBOutlet var customImageTextField: NSTextField! 15 | @IBOutlet var imageViewTextField: NSTextField! 16 | 17 | override func viewDidLoad() { 18 | super.viewDidLoad() 19 | 20 | origamiImage.image = PaintCode.imageOfOrigami 21 | 22 | // Using the colors defined in PaintCode 23 | customImageTextField.textColor = PaintCode.fillColor5 24 | imageViewTextField.textColor = PaintCode.fillColor6 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /PaintCode/PaintCode1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/PaintCode/PaintCode1.png -------------------------------------------------------------------------------- /PaintCode/ReadMe.md: -------------------------------------------------------------------------------- 1 | ## PaintCode Sample 2 | 3 | ![NSTableView](PaintCode1.png) 4 | 5 | The tutorial can be found here: https://kicsipixel.github.io/2018/paintcode/ -------------------------------------------------------------------------------- /ReadMe.md: -------------------------------------------------------------------------------- 1 | # Cocoa Sample codes 2 | ## Some very simple code for macOS Cocoa/Swift development 3 | ![](https://badgen.net/badge/language/Swift/orange) 4 | ![](https://badgen.net/badge/platform/macOS/) 5 | 6 | It is not easy to find good resources for macOS Swift development, especially if you want to create the UI programatically. Hereby I collected some of my working code snippets, maybe it will be useful. 7 | 8 | As SwiftUI is getting more popular and with v3 it can be used for macOS development too, I'm planning to create similar with SwiftUI too. (No promise :D) 9 | 10 | #### Codes 11 | - [Cocoa Binding](https://github.com/kicsipixel/Cocoa-Samples/tree/master/Cocoa%20Binding) 12 | - [MapKit with custom annotation](https://github.com/kicsipixel/Cocoa-Samples/tree/master/CustomAnnotations) 13 | - [KVC/KVO](https://github.com/kicsipixel/Cocoa-Samples/tree/master/KVC) 14 | - [MapKit for macOS](https://github.com/kicsipixel/Cocoa-Samples/tree/master/MapKitmacOS) 15 | - [Collection View on macOS](https://github.com/kicsipixel/Cocoa-Samples/tree/master/NSCollectionView) 16 | - [Outline View](https://github.com/kicsipixel/Cocoa-Samples/tree/master/NSOutlineView) 17 | - [Custom Tab View on macOS](https://github.com/kicsipixel/Cocoa-Samples/tree/master/NSTabView) 18 | - [Very minimalistic Table View](https://github.com/kicsipixel/Cocoa-Samples/tree/master/NSTableView) 19 | - [Table View with Model](https://github.com/kicsipixel/Cocoa-Samples/tree/master/NSTableView1) 20 | - [Table View with Load/Save (not document-based app)](https://github.com/kicsipixel/Cocoa-Samples/tree/master/NSTableViewWithLoad) 21 | - [PaintCode](https://github.com/kicsipixel/Cocoa-Samples/tree/master/PaintCode) 22 | - [NSWindow and NSView programatically](https://github.com/kicsipixel/Cocoa-Samples/tree/master/SemiStoryboard) 23 | - [SourceList View](https://github.com/kicsipixel/Cocoa-Samples/tree/master/SourceListView) 24 | - [Split View with Storyboard](https://github.com/kicsipixel/Cocoa-Samples/tree/master/SplitViewController) 25 | 26 | In case you need some more information, my blog can be found here: https://kicsipixel.github.io/ -------------------------------------------------------------------------------- /SemiStoryboard/ReadMe.md: -------------------------------------------------------------------------------- 1 | ## Creating NSWindow with(out) Storyboard 2 | 3 | ![SemiStoryboard](SemiStoryboard.png) 4 | 5 | This tutorial is using Storyboard only for NSMenu, but the rest of the stuff (NSWindow, NSView) is written programmatically. -------------------------------------------------------------------------------- /SemiStoryboard/SemiStoryboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/SemiStoryboard/SemiStoryboard.png -------------------------------------------------------------------------------- /SemiStoryboard/SemiStoryboard.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SemiStoryboard/SemiStoryboard.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /SemiStoryboard/SemiStoryboard.xcodeproj/project.xcworkspace/xcuserdata/szabolcs.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/SemiStoryboard/SemiStoryboard.xcodeproj/project.xcworkspace/xcuserdata/szabolcs.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /SemiStoryboard/SemiStoryboard.xcodeproj/xcuserdata/szabolcs.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | SemiStoryboard.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /SemiStoryboard/SemiStoryboard/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SemiStoryboard 4 | // 5 | // Created by Szabolcs Toth on 04/06/2020. 6 | // Copyright © 2020 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject, NSApplicationDelegate { 13 | 14 | lazy var mainWindowController = MainWindowController() 15 | 16 | func applicationDidFinishLaunching(_ aNotification: Notification) { 17 | // Insert code here to initialize your application 18 | mainWindowController.showWindow(nil) 19 | } 20 | 21 | func applicationWillTerminate(_ aNotification: Notification) { 22 | // Insert code here to tear down your application 23 | } 24 | 25 | 26 | } 27 | 28 | -------------------------------------------------------------------------------- /SemiStoryboard/SemiStoryboard/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "scale" : "1x", 6 | "size" : "16x16" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "scale" : "2x", 11 | "size" : "16x16" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "scale" : "1x", 16 | "size" : "32x32" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "scale" : "2x", 21 | "size" : "32x32" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "scale" : "1x", 26 | "size" : "128x128" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "scale" : "2x", 31 | "size" : "128x128" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "scale" : "1x", 36 | "size" : "256x256" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "scale" : "2x", 41 | "size" : "256x256" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "scale" : "1x", 46 | "size" : "512x512" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "scale" : "2x", 51 | "size" : "512x512" 52 | } 53 | ], 54 | "info" : { 55 | "author" : "xcode", 56 | "version" : 1 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /SemiStoryboard/SemiStoryboard/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /SemiStoryboard/SemiStoryboard/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2020 purzelbaum.hu. All rights reserved. 27 | NSMainStoryboardFile 28 | Main 29 | NSPrincipalClass 30 | NSApplication 31 | NSSupportsAutomaticTermination 32 | 33 | NSSupportsSuddenTermination 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /SemiStoryboard/SemiStoryboard/MainWindow.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MainWindow.swift 3 | // SemiStoryboard 4 | // 5 | // Created by Szabolcs Toth on 04/06/2020. 6 | // Copyright © 2020 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class MainWindow: NSWindow { 12 | override init(contentRect: NSRect, styleMask style: NSWindow.StyleMask, backing backingStoreType: NSWindow.BackingStoreType, defer flag: Bool) { 13 | super.init(contentRect: contentRect, styleMask: [.miniaturizable, .closable, .resizable, .titled], backing: .buffered, defer: true) 14 | isMovableByWindowBackground = true 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /SemiStoryboard/SemiStoryboard/MainWindowController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MainWindowController.swift 3 | // SemiStoryboard 4 | // 5 | // Created by Szabolcs Toth on 04/06/2020. 6 | // Copyright © 2020 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class MainWindowController: NSWindowController { 12 | 13 | convenience init() { 14 | self.init(windowNibName: "") 15 | } 16 | 17 | override func loadWindow() { 18 | // MARK: Create window 19 | let windowSize = NSSize(width: 600, height: 300) 20 | let screenSize = NSScreen.main?.frame.size ?? .zero 21 | let rect = NSMakeRect(screenSize.width/2 - windowSize.width/2, screenSize.height/2 - windowSize.height/2, windowSize.width, windowSize.height) 22 | window = MainWindow(contentRect: rect, styleMask: [], backing: .buffered, defer: true) 23 | self.window?.title = "SemiStoryboard Window" 24 | self.window?.titlebarAppearsTransparent = true 25 | self.window?.styleMask.insert(.fullSizeContentView) 26 | self.window?.contentViewController = MyViewController() 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /SemiStoryboard/SemiStoryboard/MyViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MyViewController.swift 3 | // SemiStoryboard 4 | // 5 | // Created by Szabolcs Toth on 04/06/2020. 6 | // Copyright © 2020 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class MyViewController: NSViewController { 12 | 13 | init() { 14 | super.init(nibName: nil, bundle: nil) 15 | } 16 | 17 | required init?(coder: NSCoder) { 18 | fatalError() 19 | } 20 | 21 | override func viewDidLoad() { 22 | } 23 | 24 | override func loadView() { 25 | super.viewDidLoad() 26 | self.view = NSView() 27 | view.frame.size = CGSize(width: 600, height: 300) 28 | view.wantsLayer = true 29 | view.layer?.backgroundColor = NSColor.white.cgColor 30 | 31 | let label = NSTextField() 32 | label.frame = CGRect(x: 0, y: 0, width: 100, height: 44) 33 | label.stringValue = "Hello, World!" 34 | label.backgroundColor = .white 35 | label.isBezeled = false 36 | label.isEditable = false 37 | label.sizeToFit() 38 | view.addSubview(label) 39 | 40 | label.translatesAutoresizingMaskIntoConstraints = false 41 | let labelConstraint = [ 42 | label.centerXAnchor.constraint(equalTo: view.centerXAnchor), 43 | label.centerYAnchor.constraint(equalTo: view.centerYAnchor), 44 | ] 45 | NSLayoutConstraint.activate(labelConstraint) 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /SemiStoryboard/SemiStoryboard/SemiStoryboard.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /SlidingView/README.md: -------------------------------------------------------------------------------- 1 | # Sliding View 2 | 3 | ![](SlidingView.png) 4 | 5 | I kept the NSWindow and NSView + ViewController from Storyboard and added the additional Views and Button programatically. -------------------------------------------------------------------------------- /SlidingView/SlidingView.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/SlidingView/SlidingView.png -------------------------------------------------------------------------------- /SlidingView/SlidingViews.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SlidingView/SlidingViews.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /SlidingView/SlidingViews.xcodeproj/project.xcworkspace/xcuserdata/szabolcs.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/SlidingView/SlidingViews.xcodeproj/project.xcworkspace/xcuserdata/szabolcs.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /SlidingView/SlidingViews.xcodeproj/xcuserdata/szabolcs.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | SlidingViews.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /SlidingView/SlidingViews/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SlidingViews 4 | // 5 | // Created by Szabolcs Tóth on 2021. 08. 27.. 6 | // 7 | 8 | import Cocoa 9 | 10 | @main 11 | class AppDelegate: NSObject, NSApplicationDelegate { 12 | 13 | 14 | 15 | 16 | func applicationDidFinishLaunching(_ aNotification: Notification) { 17 | // Insert code here to initialize your application 18 | } 19 | 20 | func applicationWillTerminate(_ aNotification: Notification) { 21 | // Insert code here to tear down your application 22 | } 23 | 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /SlidingView/SlidingViews/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SlidingView/SlidingViews/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "scale" : "1x", 6 | "size" : "16x16" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "scale" : "2x", 11 | "size" : "16x16" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "scale" : "1x", 16 | "size" : "32x32" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "scale" : "2x", 21 | "size" : "32x32" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "scale" : "1x", 26 | "size" : "128x128" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "scale" : "2x", 31 | "size" : "128x128" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "scale" : "1x", 36 | "size" : "256x256" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "scale" : "2x", 41 | "size" : "256x256" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "scale" : "1x", 46 | "size" : "512x512" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "scale" : "2x", 51 | "size" : "512x512" 52 | } 53 | ], 54 | "info" : { 55 | "author" : "xcode", 56 | "version" : 1 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /SlidingView/SlidingViews/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /SlidingView/SlidingViews/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSMainStoryboardFile 26 | Main 27 | NSPrincipalClass 28 | NSApplication 29 | 30 | 31 | -------------------------------------------------------------------------------- /SlidingView/SlidingViews/SlidingViews.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /SlidingView/SlidingViews/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // SlidingViews 4 | // 5 | // Created by Szabolcs Tóth on 2021. 08. 27.. 6 | // 7 | 8 | import Cocoa 9 | 10 | class ViewController: NSViewController { 11 | 12 | private let redView: NSView = { 13 | let view = NSView(frame: NSRect(x: 0, y: 0, width: 20, height: 20)) 14 | view.wantsLayer = true 15 | view.layer?.backgroundColor = NSColor.red.cgColor 16 | view.translatesAutoresizingMaskIntoConstraints = false 17 | return view 18 | }() 19 | 20 | private let helloWorldLabelForRedView: NSTextField = { 21 | let label = NSTextField(frame: CGRect(x: 0, y: 0, width: 100, height: 44)) 22 | label.stringValue = "Hello, World! I'm a red view." 23 | label.isEditable = false 24 | label.isBezeled = false 25 | label.backgroundColor = .clear 26 | label.sizeToFit() 27 | label.translatesAutoresizingMaskIntoConstraints = false 28 | return label 29 | }() 30 | 31 | private let removeRedViewButton: NSButton = { 32 | let button = NSButton(frame: NSRect(x: 0, y: 0, width: 100, height: 40)) 33 | button.title = "Move, Red View!" 34 | button.action = #selector(redAnimation) 35 | button.bezelStyle = .regularSquare 36 | button.translatesAutoresizingMaskIntoConstraints = false 37 | return button 38 | }() 39 | 40 | // Be more creative about naming 41 | private let helloWorldLabelForDefaultView: NSTextField = { 42 | let label = NSTextField(frame: CGRect(x: 0, y: 0, width: 0, height: 0)) 43 | label.stringValue = "Hello, World!" 44 | label.isEditable = false 45 | label.isBezeled = false 46 | label.backgroundColor = .clear 47 | label.sizeToFit() 48 | label.translatesAutoresizingMaskIntoConstraints = false 49 | return label 50 | }() 51 | 52 | override func viewDidLoad() { 53 | super.viewDidLoad() 54 | 55 | // Building UI 56 | view.addSubview(helloWorldLabelForDefaultView) 57 | view.addSubview(redView) 58 | view.addSubview(removeRedViewButton) 59 | redView.addSubview(helloWorldLabelForRedView) 60 | 61 | // Red View constraints 62 | let redViewConstraint = [ 63 | redView.centerXAnchor.constraint(equalTo: view.centerXAnchor), 64 | redView.topAnchor.constraint(equalTo: view.topAnchor), 65 | redView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.85), 66 | redView.widthAnchor.constraint(equalTo: view.widthAnchor) 67 | ] 68 | NSLayoutConstraint.activate(redViewConstraint) 69 | 70 | // NSTextField constraints 71 | let helloWorldLabelForRedViewConstraint = [ 72 | helloWorldLabelForRedView.centerXAnchor.constraint(equalTo: redView.centerXAnchor), 73 | helloWorldLabelForRedView.centerYAnchor.constraint(equalTo: redView.centerYAnchor) 74 | ] 75 | NSLayoutConstraint.activate(helloWorldLabelForRedViewConstraint) 76 | 77 | // NSBUtton constraints 78 | let removeRedViewButtonConstraint = [ 79 | removeRedViewButton.centerXAnchor.constraint(equalTo: view.centerXAnchor), 80 | removeRedViewButton.centerYAnchor.constraint(equalTo: view.bottomAnchor, constant: -20) 81 | ] 82 | NSLayoutConstraint.activate(removeRedViewButtonConstraint) 83 | 84 | // NSTextField constaints again... 85 | let helloWorldLabelForDefaultViewConstaint = [ 86 | helloWorldLabelForDefaultView.centerXAnchor.constraint(equalTo: view.centerXAnchor), 87 | helloWorldLabelForDefaultView.centerYAnchor.constraint(equalTo: view.centerYAnchor) 88 | ] 89 | NSLayoutConstraint.activate(helloWorldLabelForDefaultViewConstaint) 90 | } 91 | 92 | @objc func redAnimation() { 93 | let animationFromLeft = CABasicAnimation(keyPath: "position.x") 94 | animationFromLeft.timingFunction = .init(name: CAMediaTimingFunctionName.easeInEaseOut) 95 | animationFromLeft.duration = 3 96 | animationFromLeft.toValue = -480 97 | animationFromLeft.autoreverses = false 98 | 99 | redView.layer?.add(animationFromLeft, forKey: nil) 100 | 101 | CATransaction.setCompletionBlock { 102 | DispatchQueue.main.asyncAfter(deadline: .now() + 2.6) { 103 | self.redView.layer?.position.x = -480 104 | } 105 | } 106 | CATransaction.commit() 107 | } 108 | } 109 | 110 | -------------------------------------------------------------------------------- /SourceListView/ReadMe.md: -------------------------------------------------------------------------------- 1 | ## SourceListView Sample 2 | ![SourceListView](SourceListView.png) -------------------------------------------------------------------------------- /SourceListView/SourceListView.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/SourceListView/SourceListView.png -------------------------------------------------------------------------------- /SourceListView/SourceListView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SourceListView/SourceListView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /SourceListView/SourceListView.xcodeproj/project.xcworkspace/xcuserdata/szabolcs.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/SourceListView/SourceListView.xcodeproj/project.xcworkspace/xcuserdata/szabolcs.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /SourceListView/SourceListView.xcodeproj/xcuserdata/szabolcs.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /SourceListView/SourceListView.xcodeproj/xcuserdata/szabolcs.xcuserdatad/xcschemes/SourceListView.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /SourceListView/SourceListView.xcodeproj/xcuserdata/szabolcs.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | SourceListView.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 57D3473A1EF1A3F6004493DD 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /SourceListView/SourceListView/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SourceListView 4 | // 5 | // Created by Szabolcs Toth on 6/14/17. 6 | // Copyright © 2017 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject, NSApplicationDelegate { 13 | 14 | 15 | 16 | func applicationDidFinishLaunching(_ aNotification: Notification) { 17 | // Insert code here to initialize your application 18 | } 19 | 20 | func applicationWillTerminate(_ aNotification: Notification) { 21 | // Insert code here to tear down your application 22 | } 23 | 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /SourceListView/SourceListView/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /SourceListView/SourceListView/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /SourceListView/SourceListView/Assets.xcassets/Germany.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Germany.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /SourceListView/SourceListView/Assets.xcassets/Germany.imageset/Germany.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/SourceListView/SourceListView/Assets.xcassets/Germany.imageset/Germany.png -------------------------------------------------------------------------------- /SourceListView/SourceListView/Assets.xcassets/Hungary.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Hungary.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /SourceListView/SourceListView/Assets.xcassets/Hungary.imageset/Hungary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/SourceListView/SourceListView/Assets.xcassets/Hungary.imageset/Hungary.png -------------------------------------------------------------------------------- /SourceListView/SourceListView/Assets.xcassets/Japan.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Japan.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /SourceListView/SourceListView/Assets.xcassets/Japan.imageset/Japan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/SourceListView/SourceListView/Assets.xcassets/Japan.imageset/Japan.png -------------------------------------------------------------------------------- /SourceListView/SourceListView/Assets.xcassets/Mexico.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Mexico.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /SourceListView/SourceListView/Assets.xcassets/Mexico.imageset/Mexico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/SourceListView/SourceListView/Assets.xcassets/Mexico.imageset/Mexico.png -------------------------------------------------------------------------------- /SourceListView/SourceListView/Country.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Country.swift 3 | // SourceListView 4 | // 5 | // Created by Szabolcs Toth on 6/14/17. 6 | // Copyright © 2017 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | struct City { 12 | var cityName: String 13 | } 14 | 15 | struct Country { 16 | var countryName: String 17 | var flag: NSImage 18 | var cities: [City] = [] 19 | } 20 | 21 | struct Continent { 22 | var continentName: String 23 | var countries: [Country] = [] 24 | } 25 | -------------------------------------------------------------------------------- /SourceListView/SourceListView/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2017 purzelbaum.hu. All rights reserved. 27 | NSMainStoryboardFile 28 | Main 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /SourceListView/SourceListView/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // SourceListView 4 | // 5 | // Created by Szabolcs Toth on 6/14/17. 6 | // Copyright © 2017 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class ViewController: NSViewController, NSOutlineViewDelegate, NSOutlineViewDataSource { 12 | 13 | @IBOutlet var outlineView: NSOutlineView! 14 | 15 | var continent1 = Continent(continentName: "Europe") 16 | var continent2 = Continent(continentName: "Asia") 17 | var continent3 = Continent(continentName: "Americas") 18 | 19 | override func viewDidLoad() { 20 | super.viewDidLoad() 21 | 22 | let city1 = City(cityName: "Berlin") 23 | let city2 = City(cityName: "Budapest") 24 | let city3 = City(cityName: "Tokyo") 25 | let city4 = City(cityName: "Mexico city") 26 | 27 | var country1 = Country(countryName: "Germany", flag: NSImage(named:"Germany")!) 28 | var country2 = Country(countryName: "Hungary", flag: NSImage(named:"Hungary")!) 29 | var country3 = Country(countryName: "Japan", flag: NSImage(named:"Japan")!) 30 | var country4 = Country(countryName: "Mexico", flag: NSImage(named:"Mexico")!) 31 | 32 | country1.cities.append(city1) 33 | country2.cities.append(city2) 34 | country3.cities.append(city3) 35 | country4.cities.append(city4) 36 | 37 | continent1.countries.append(country1) 38 | continent1.countries.append(country2) 39 | continent2.countries.append(country3) 40 | continent3.countries.append(country4) 41 | } 42 | 43 | func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int { 44 | if let item: Any = item { 45 | switch item { 46 | case let continent as Continent: 47 | return continent.countries.count 48 | case let country as Country: 49 | return country.cities.count 50 | default: 51 | return 0 52 | } 53 | } else { 54 | return 3 55 | } 56 | } 57 | 58 | func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any { 59 | if let item: Any = item { 60 | switch item { 61 | case let continent as Continent: 62 | return continent.countries[index] 63 | case let country as Country: 64 | return country.cities[index] 65 | default: 66 | return self 67 | } 68 | } else { 69 | switch index { 70 | case 0: 71 | return continent1 72 | case 1: 73 | return continent2 74 | default: 75 | return continent3 76 | } 77 | } 78 | } 79 | 80 | func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: Any) -> Bool { 81 | switch item { 82 | case let continent as Continent: 83 | return (continent.countries.count > 0) ? true : false 84 | case let country as Country: 85 | return (country.cities.count > 0) ? true: false 86 | default: 87 | return false 88 | } 89 | } 90 | 91 | 92 | func outlineView(_ outlineView: NSOutlineView, isGroupItem item: Any) -> Bool { 93 | switch item { 94 | case let continent as Continent: 95 | return true /* 96 | case let country as Country: 97 | return true */ 98 | default: 99 | return false 100 | } 101 | } 102 | 103 | func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? { 104 | switch item { 105 | case let continent as Continent: 106 | let view = outlineView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "HeaderCell"), owner: self) as! NSTableCellView 107 | if let textField = view.textField { 108 | textField.stringValue = continent.continentName 109 | } 110 | return view 111 | 112 | case let country as Country: 113 | let view = outlineView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "DataCell"), owner: self) as! NSTableCellView 114 | if let textField = view.textField { 115 | textField.stringValue = country.countryName 116 | } 117 | 118 | let flagImage = country.flag 119 | view.imageView?.image = flagImage 120 | return view 121 | 122 | case let city as City: 123 | let view = outlineView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "DataCell"), owner: self) as! NSTableCellView 124 | 125 | if let textField = view.textField { 126 | textField.stringValue = city.cityName 127 | textField.frame.origin.x = 18.0 128 | } 129 | view.imageView?.image = nil 130 | return view 131 | 132 | default: 133 | return nil 134 | } 135 | } 136 | 137 | } 138 | 139 | -------------------------------------------------------------------------------- /SplitViewController/ReadMe.md: -------------------------------------------------------------------------------- 1 | ## SplitViewController Sample 2 | 3 | **This solution worked but was not proper and I removed it. Working on a better one.** 4 | 5 | Most probably not the most efficient and beautiful implementation of SplitViewController, but at least it works... :) 6 | Suggestions are welcome. 7 | 8 | **Update 03/12/2019** 9 | After some time I have returned to this project and finished. I think this is much better implementation. 10 | 11 | ![SplitViewController](SplitViewController.png) -------------------------------------------------------------------------------- /SplitViewController/SplitViewController.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/SplitViewController/SplitViewController.png -------------------------------------------------------------------------------- /SplitViewController/SplitViewController/SplitViewController.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SplitViewController/SplitViewController/SplitViewController.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /SplitViewController/SplitViewController/SplitViewController.xcodeproj/project.xcworkspace/xcuserdata/szabolcs.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kicsipixel/Cocoa-Samples/e10bae2b11e30550890a9aa6bd3a66daee8801fa/SplitViewController/SplitViewController/SplitViewController.xcodeproj/project.xcworkspace/xcuserdata/szabolcs.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /SplitViewController/SplitViewController/SplitViewController.xcodeproj/xcuserdata/szabolcs.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | SplitViewController.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /SplitViewController/SplitViewController/SplitViewController/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SplitViewController 4 | // 5 | // Created by Szabolcs Toth on 30/11/2019. 6 | // Copyright © 2019 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject, NSApplicationDelegate { 13 | 14 | 15 | 16 | func applicationDidFinishLaunching(_ aNotification: Notification) { 17 | // Insert code here to initialize your application 18 | } 19 | 20 | func applicationWillTerminate(_ aNotification: Notification) { 21 | // Insert code here to tear down your application 22 | } 23 | 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /SplitViewController/SplitViewController/SplitViewController/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /SplitViewController/SplitViewController/SplitViewController/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /SplitViewController/SplitViewController/SplitViewController/DetailViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DetailViewController.swift 3 | // SplitViewController 4 | // 5 | // Created by Szabolcs Toth on 30/11/2019. 6 | // Copyright © 2019 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class DetailViewController: NSViewController { 12 | 13 | @IBOutlet var tableView: NSTableView! 14 | var dataArray = [Person]() 15 | 16 | override func viewDidLoad() { 17 | super.viewDidLoad() 18 | // Do view setup here. 19 | } 20 | 21 | func dataFromOtherView(data: Any) { 22 | if let data = data as? Family { 23 | // Empty the array 24 | dataArray.removeAll() 25 | dataArray = data.members 26 | tableView.reloadData() 27 | } 28 | 29 | if let data = data as? Person { 30 | // Empty array 31 | dataArray.removeAll() 32 | dataArray.append(data) 33 | tableView.reloadData() 34 | } 35 | } 36 | } 37 | 38 | extension DetailViewController: NSTableViewDataSource, NSTableViewDelegate { 39 | 40 | func numberOfRows(in tableView: NSTableView) -> Int { 41 | return dataArray.count 42 | } 43 | 44 | func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { 45 | let person = dataArray[row] 46 | 47 | guard let cell = tableView.makeView(withIdentifier: tableColumn!.identifier, owner: self) as? NSTableCellView else { return nil } 48 | 49 | if (tableColumn?.identifier)!.rawValue == "firstName" { 50 | cell.textField?.stringValue = person.firstName 51 | } else { 52 | cell.textField?.stringValue = person.lastName 53 | } 54 | 55 | return cell 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /SplitViewController/SplitViewController/SplitViewController/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2019 purzelbaum.hu. All rights reserved. 27 | NSMainStoryboardFile 28 | Main 29 | NSPrincipalClass 30 | NSApplication 31 | NSSupportsAutomaticTermination 32 | 33 | NSSupportsSuddenTermination 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /SplitViewController/SplitViewController/SplitViewController/Person.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Person.swift 3 | // SplitViewController 4 | // 5 | // Created by Szabolcs Toth on 30/11/2019. 6 | // Copyright © 2019 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Person { 12 | var firstName: String 13 | var lastName: String 14 | } 15 | 16 | struct Family { 17 | var members: [Person] = [] 18 | var familyName: String 19 | } 20 | -------------------------------------------------------------------------------- /SplitViewController/SplitViewController/SplitViewController/SplitViewController.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /SplitViewController/SplitViewController/SplitViewController/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // SplitViewController 4 | // 5 | // Created by Szabolcs Toth on 30/11/2019. 6 | // Copyright © 2019 purzelbaum.hu. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class ViewController: NSViewController, NSOutlineViewDelegate, NSOutlineViewDataSource { 12 | 13 | @IBOutlet var outlineView: NSOutlineView! 14 | 15 | var family1 = Family(familyName: "Walton") 16 | var family2 = Family(familyName: "Porsche") 17 | var people = [Person]() 18 | 19 | override func viewDidLoad() { 20 | super.viewDidLoad() 21 | 22 | let person1 = Person(firstName: "Jim", lastName: "Walton") 23 | people.append(person1) 24 | 25 | let person2 = Person(firstName: "Alice", lastName: "Walton") 26 | people.append(person2) 27 | 28 | let person3 = Person(firstName: "Wolfgang", lastName: "Porsche") 29 | people.append(person3) 30 | 31 | let person4 = Person(firstName: "S. Robson", lastName: "Walton") 32 | people.append(person4) 33 | 34 | let person5 = Person(firstName: "Lukas", lastName: "Walton") 35 | people.append(person5) 36 | 37 | for person in people { 38 | if person.lastName == family1.familyName { 39 | family1.members.append(person) 40 | } else { 41 | family2.members.append(person) 42 | } 43 | } 44 | 45 | } 46 | 47 | override var representedObject: Any? { 48 | didSet { 49 | // Update the view, if already loaded. 50 | } 51 | } 52 | 53 | func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int { 54 | if let item: Any = item { 55 | switch item { 56 | case let family as Family: 57 | return family.members.count 58 | default: 59 | return 0 60 | } 61 | } else { 62 | return 2 63 | } 64 | } 65 | 66 | func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any { 67 | if let item: Any = item { 68 | switch item { 69 | case let family as Family: 70 | return family.members[index] 71 | default: 72 | return self 73 | } 74 | } else { 75 | switch index { 76 | case 0: 77 | return family1 78 | default: 79 | return family2 80 | } 81 | } 82 | } 83 | 84 | func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: Any) -> Bool { 85 | switch item { 86 | case let family as Family: 87 | return (family.members.count > 0) ? true : false 88 | default: 89 | return false 90 | } 91 | } 92 | 93 | 94 | func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? { 95 | switch item { 96 | case let family as Family: 97 | let view = outlineView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "DataCell"), owner: self) as! NSTableCellView 98 | if let textField = view.textField { 99 | textField.stringValue = family.familyName 100 | } 101 | return view 102 | 103 | case let person as Person: 104 | let view = outlineView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "DataCell"), owner: self) as! NSTableCellView 105 | if let textField = view.textField { 106 | textField.stringValue = person.firstName 107 | } 108 | return view 109 | 110 | default: 111 | return nil 112 | } 113 | } 114 | 115 | func outlineViewSelectionDidChange(_ notification: Notification) { 116 | let selectedRow = outlineView.selectedRow 117 | 118 | guard let splitVC = parent as? NSSplitViewController else { return } 119 | 120 | // Nothing is selected 121 | if selectedRow == -1 { 122 | return 123 | } 124 | 125 | if let item = outlineView.item(atRow: selectedRow) { 126 | 127 | // If the selected row category or subitem 128 | if let item = item as? Family { 129 | if let detail = splitVC.children[1] as? DetailViewController { 130 | detail.dataFromOtherView(data: item) 131 | } 132 | } else if let item = item as? Person { 133 | if let detail = splitVC.children[1] as? DetailViewController { 134 | detail.dataFromOtherView(data: item) 135 | } 136 | } 137 | } 138 | } 139 | 140 | } 141 | 142 | --------------------------------------------------------------------------------