{"id":19190841,"url":"https://github.com/flocked/fzuikit","last_synced_at":"2026-02-19T18:05:48.954Z","repository":{"id":169263956,"uuid":"645181131","full_name":"flocked/FZUIKit","owner":"flocked","description":"Swift AppKit/UIKit extensions, classes and utilities","archived":false,"fork":false,"pushed_at":"2026-02-12T21:50:08.000Z","size":123845,"stargazers_count":17,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-13T00:39:37.439Z","etag":null,"topics":["appkit","macos","swift","uikit"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/flocked.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-05-25T05:18:47.000Z","updated_at":"2026-02-12T21:50:11.000Z","dependencies_parsed_at":"2024-02-11T03:29:19.800Z","dependency_job_id":"faf962ca-955f-41f9-bf3e-b682fa626a5e","html_url":"https://github.com/flocked/FZUIKit","commit_stats":null,"previous_names":["flocked/fzuikit"],"tags_count":25,"template":false,"template_full_name":null,"purl":"pkg:github/flocked/FZUIKit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flocked%2FFZUIKit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flocked%2FFZUIKit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flocked%2FFZUIKit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flocked%2FFZUIKit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/flocked","download_url":"https://codeload.github.com/flocked/FZUIKit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flocked%2FFZUIKit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29626690,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-19T18:02:07.722Z","status":"ssl_error","status_checked_at":"2026-02-19T18:01:46.144Z","response_time":117,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["appkit","macos","swift","uikit"],"created_at":"2024-11-09T11:35:58.180Z","updated_at":"2026-02-19T18:05:48.949Z","avatar_url":"https://github.com/flocked.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FZUIKit\n\nA framework with Swift AppKit and UIKit extensions, classes \u0026 utilities.\n\n**Always use the main branch, as else the package might not compile probably.**\n\n**For a full documentation take a look at the included documentation located at */Documentation*. Opening the file launches Xcode's documentation browser.**\n\n## Notable Extensions \u0026 Classes\n\n### NSContentConfiguration \u0026 NSContentView\n\nA port of `UIContentConfiguration` \u0026 `UIContentView` to AppKit.\n\n#### NSHostingConfiguration\n\nA content configuration suitable for hosting a hierarchy of SwiftUI views.\n\n```swift\nlet configuration = NSHostingConfiguration() {\n    Label(\"Your account\", systemImage: \"folder.circle\")\n}\n\ncollectionViewItem.contentConfiguration = configuration\n```\n\n#### NSBackgroundConfiguration\n\nA content configuration suitable for backgrounds.\n\n```swift\nvar configuration = NSBackgroundConfiguration()\n\nconfiguration.backgroundColor = .controlAccentColor\nconfiguration.cornerRadius = 6.0\nconfiguration.shadow = .black\nconfiguration.imageProperties.tintColor = .purple\n\nlet backgroundView = NSBackgroundView(configuration: configuration)\n```\n\n#### NSContentUnavailableConfiguration\n\nA content configuration for a content-unavailable view. It is a composable description of a view indicating your app can’t display content. Using a content-unavailable configuration, you can obtain system default styling for a variety of different empty states. \n\n```swift\nlet configuration = NSContentUnavailableConfiguration.loading() // A loading view that is displaying a spinning indicator.\n\nconfiguration.text = \"Loading…\"\nconfiguration.secondaryText = \"The database is getting loaded.\"\n\nlet loadingView = NSContentUnavailableView(configuration: configuration)\n```\n\n### NSView extensions\n\n- `backgroundColor`: The background color of a view that automatically adjusts on light/dark mode changes and can be animated via `animator()`.\n\n```swift\nview.backgroundColor = .systemRed\n```\n\n- `mask`: Masks a view with another view whose alpha channel is used for masking.\n\n```swift\nview.mask = roundedView\n```\n\n- Properties that can be all animated via the views `animator()`:\n    - `cornerRadius: CGFloat`\n    - `cornerCurve: CALayerCornerCurve`\n    - `roundedCorners: CACornerMask`\n    - `borderWidth: CGFloat`\n    - `borderColor: NSColor? `\n    - `center: CGPoint`\n    - `transform: CGAffineTransform`\n    - `transform3D: CATransform3D`\n    - `anchorPoint: CGPoint`\n    - NSTextField: `fontSize: CGFloat`\n\n- `menuProvider`:  Provides a right click menu.\n\n```swift\ntableView.menuProvider = { mouseLocation in\n    let menu = NSMenu()\n    menu.addItem(NSMenuItem(title: \"\\(selectedRowIndexes.count) rows selected\"))\n    return mneu\n}\n```\n- `WindowHandlers`:\n\n```swift\n// Some examples:\nview.windowHandlers.window = { newWindow in\n    // handle newWindow\n}\nview.windowHandlers.isKey = { isKey in\n    // handle window isKey\n}\n```\n- `MouseHandlers`:\n\n```swift\n// Some examples:\nview.mouseHandlers.down = { mouseDown in\n    // handle mouse click\n}\nview.mouseHandlers.moved = { mouseMoved in\n    // handle mouse move\n}\n```\n\n- `ViewHandlers`:\n\n```swift\n// Some examples:\nview.viewHandlers.superview = { newSuperview in\n    // handle superview change\n}\nview.viewHandlers.frame = { frame in\n    // handle frame change\n}\nview.viewHandlers.effectiveAppearance { appearance in\n    // handle appearance change\n}\n```\n\n- `DropHandlers` for dropping files to the view:\n\n```swift\nview.dropHandlers.canDrop = { items, mouseLocation in\n    if items.images?.isEmpty == false || items.fileURLs?.isEmpty == false {\n        return true\n    } else {\n        return false\n    }\n}\n     \nview.dropHandlers.didDrop = { items, mouseLocation in\n    if let images = items.images {\n        // handle dropped images\n    }\n    if let fileURLs = items.fileURLs {\n        // handle dropped file urls\n    }\n}\n```\n\n- Convenience way of animating view properties:\n\n```swift\nview.animate(duration: 0.5) {\n    $0.cornerRadius = 4.0\n    $0.borderWidth = 2.0\n    $0.borderColor = .controlAccentColor\n}\n```\n\n### NSImage prepareForDisplay \u0026 prepareThumbnail\n\nAn `UIImage` port for generating thumbnails and to prepare and decode images to provide much better performance displaying them. It offers synchronous and asynchronous (either via asyc/await or completionHandler) implementations.\n\n```swift\n// prepared decoded image for better performance\nlet preparedImage = await image.preparingForDisplay() \n\n// thumbnail image\nlet maxThumbnailSize = CGSize(width: 512, height: 512)\nimage.prepareThumbnail(of: maxThumbnailSize) { thumbnailImage in\n    // thumbnailImage…\n}\n```\n\n### Content Configurations\n\nConfigurates several aspects of views, windows, etc. Examples:\n\n- VisualEffect: Adds a visual effect to the background\n```swift\nwindow.visualEffect = .darkAqua()\nview.visualEffect = .vibrantLight(material: .sidebar)\n```\n\n- Shadow/InnerShadow:\n```swift\nlet shadow = ShadowConfiguration(color: .controlAccentColor, opacity: 0.5, radius: 3.0)\nview.outerShadow = shadow\n\n// inner shadow\nview.innerShadow = shadow\n```\n\n- Border\n```swift\nlet border = BorderConfiguration(color: .black, width: 1.0)\nview.border = border\n\nlet dashedBorder: BorderConfiguration = .dashed(color: .red)\nview.border = dashedBorder\n```\n\n- SymbolConfiguration: A simplified version of `UIImage/NSImage.SymbolConfiguration`.\n```swift\nlet symbolConfiguration: ImageSymbolConfiguration = .hierarchical(color: .red)\nsymbolConfiguration.font = .body\nsymbolConfiguration.imageScaling = .large\nimageView.configurate(using: symbolConfiguration)\n```\n\n- Text\n```swift\nvar textConfiguration = TextConfiguration()\ntextConfiguration.font = .body\ntextConfiguration.color = .systemRed\ntextConfiguration.numberOfLines = 1\ntextConfiguration.adjustsFontSizeToFitWidth = true\ntextField.configurate(using: textConfiguration)\n```\n\n### NSSegmentedControl Segments\n\nConfigurates the segments of a NSSegmentedControl:\n\n```swift\nlet segmentedControl = NSSegmentedControl() {\n    NSSegment(\"Segment 1\").isSelected(true)\n    NSSegment(\"Segment 2\"), \n    NSSegment(NSImage(named: \"myImage\")!)\n    NSSegment(symbolName: \"photo\")\n}\n```\n\n### NSTextField\n\n- `adjustsFontSizeToFitWidth` and `minimumScaleFactor` (Port of UILabel)\n\n```swift\ntextField.adjustsFontSizeToFitWidth = true\ntextField.minimumScaleFactor = 0.7\n```\n\n- `minimumNumberOfCharacters`, `maximumNumberOfCharacters` and `allowedCharacters`\n\n```swift\ntextField.maximumNumberOfCharacters = 20\ntextField.allowedCharacters = [.lowercaseLetters, .digits, .emojis]\n```\n\n- `actionOnEnterKeyDown`, `actionOnEscapeKeyDown` \u0026 `endEditingOnOutsideMouseDown`:\n\n```swift\n// Ends editing on enter/return.\ntextField.actionOnEnterKeyDown = .endEditing\n// Cancels editing on escape and resets the text to the previous state.\ntextField.actionOnEscapeKeyDown = .endEditingAndReset\n// Ends editing when the user clicks outside the text field.\ntextField.endEditingOnOutsideMouseDown = true\n```\n\n- `automaticallyResizesToFit`: Automatically adjust the text field size to fit it's text'.\n\n- `EditingHandlers`:\n\n```swift\ntextField.editingHandlers.didBegin {\n    // Editing of the text did begin\n}\ntextField.editingHandlers.didEdit {\n    // Text did change\n}\ntextField.editingHandlers.shouldEdit { \n    newText in \n    return true\n}\n```\n\n### NSToolbar\nConfigurate the items of a NSToolbar.\n\n```swift\nlet toolbar = Toolbar(\"ToolbarIdentifier\") {\n        Button(\"OpenItem\", title: \"Open…\")\n            .onAction() { /// Button pressed }\n        FlexibleSpace()\n        Segmented(\"SegmentedItem\") {\n            Segment(\"Segment 1\", isSelected: true)\n            Segment(\"Segment 2\"),\n        }.onAction() { /// Segmented pressed }\n        Search(\"SearchItem\")\n            .onSearch() { searchField, stringValue, state in /// Searching }\n}\ntoolbar.attachedWindow = window\n```\n\n### NSMenu\n\nConfigurate the items of a Menu.\n\n```swift\nlet menu = NSMenu() {\n    NSMenuItem(\"Open…\")\n        .onSelect() { // Open item Pressed }\n    NSMenuItem(\"Delete\")\n        .onSelect() { // Delete item Pressed }\n    NSMenuItem.seperator()\n    NSMenuItem() {\n        HStack {\n            Circle().forgroundColor(.red)\n            Circle().forgroundColor(.blue)\n        }\n    }\n}\n```\n\n### DateTextFieldLabel\n\nA text field with a date property that automatically updates its string baased on date. It can show the date absolute or relative.\n\n```swift\nlet textField = DateTextField(date: Date())\ntextField.dateDisplayMode = .relative // It displays e.g. \"2 mins ago\"\ntextField.dateDisplayMode = .absolute // It displays e.g. \"04.04.2023 10:20pm\"\n```\n\n### SpacerView\n\nA spacer for `NSStackView/UIStackView` that expands along the major axis of it's containing stack view. It works as `SwiftUI` spacer.\n\n### ResizingTextField\n\nA `NSTextField` that automatically resizes to fit it's text.\n\n```swift\nlet textField = ResizingTextField(string: \"Some string\")\ntextField.automaticallyResizesToFit = true\ntextField.maxWidth = 200 // The max width of the text field when resizing.\n```\n\n### ImageView\n\nAn advanced `NSImageView` that supports scaleToFill, multiple images, gif animation speed, etc.\n\n```swift\nlet imageView = ImageView()\nimageView.imageScaling = .resizeAspectFill\nimageView.image = myGifImage\nimageView.animationDuration = 3.0 /// gif animation speed\nimageView.animationPlaybackOption = .mouseHover /// animation plays on mouse hover\nimageView.animationPlaybackOption = .mouseDown /// toggle playback via mouse click\n```\n\n### AVPlayer extensions\n\n- `isLooping`: Easy looping of the playing item.\n\n```swift\nplayer.isLooping = true\n```\n\n- `state`: The current playback state of the player: .isPlaying, .isPaused, .isStopped, .error(Error)\n- `seek(toPercentage: Double)`\n\n### NSMagnificationGestureRecognizer extension\n\n- `velocity`: The velocity of the magnification in scale factor per second.\n\n### DisplayLinkeTimer\n\nA much more precise `Timer` which time interval can be changed without invalidating the timer.\n\n```swift\nlet timer = DisplayLinkTimer.scheduledTimer(timeInterval: .seconds(3.0), action: {\n    // some action\n})\ntimer.timeInterval = .minutes(1)\n```\n\n### NSAlert `supressionKey`\n     \nProvide a supression key to `NSAlert` to allow the user to opt out of showing the alert again by showing a suppression checkbox.\n     \nIf the user opts out, the alert won't be shown again and will instead return as response `suppress`.\n     \n```swift\nlet alert = NSAlert.informational(\"My Alert\")\nalert.supressionKey = \"someKey\"\n\nlet response = alert.runModal()\nif response == .suppress {\n    // The alert was suppressed\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflocked%2Ffzuikit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflocked%2Ffzuikit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflocked%2Ffzuikit/lists"}