I'm trying to bind a NSProgressIndicator to Progress, but with the following code I only get an indeterminate progress indicator with a blue bar forever bouncing left and right, even after the two timers fire. According to the documentation:
Progress is indeterminate when the value of the totalUnitCount or completedUnitCount is less than zero or if both values are zero.
What am I doing wrong?
class ViewController: NSViewController {
let progress = Progress()
override func loadView() {
view = NSView(frame: CGRect(x: 0, y: 0, width: 500, height: 500))
let progressIndicator = NSProgressIndicator(frame: CGRect(x: 100, y: 100, width: 100, height: 100))
progressIndicator.bind(.isIndeterminate, to: progress, withKeyPath: "isIndeterminate")
progressIndicator.bind(.value, to: progress, withKeyPath: "completedUnitCount")
progressIndicator.bind(.maxValue, to: progress, withKeyPath: "totalUnitCount")
progressIndicator.startAnimation(nil)
view.addSubview(progressIndicator)
progress.completedUnitCount = 3
progress.totalUnitCount = 10
Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { _ in
print(1)
self.progress.completedUnitCount = 6
}
Timer.scheduledTimer(withTimeInterval: 6, repeats: false) { _ in
print(2)
self.progress.completedUnitCount = 0
self.progress.totalUnitCount = 0
}
}
}
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
A user of my app, which shows subtitles loaded from a text file above a video loaded from another file, reported that it crashes within minutes of launching it. The user confirmed that the crash only happens when they load a video within the app; if they use it without a video, it doesn't crash. The subtitles are shown in a NSTextView added to AVPlayerView.contentOverlayView.
What could cause such a crash? I'm not able to reproduce it.
(I tried attaching the full crash report but I always got a validation error "This post contains sensitive language. Please revise it in order to continue.")
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x000000019c50cae8
Termination Reason: Namespace SIGNAL, Code 5 Trace/BPT trap: 5
Terminating Process: exc handler [20614]
Application Specific Backtrace 0:
0 CoreFoundation 0x0000000198a472ec __exceptionPreprocess + 176
1 libobjc.A.dylib 0x000000019852e788 objc_exception_throw + 60
2 Foundation 0x0000000199b2caa0 -[NSKeyValueNestedProperty object:withObservance:didChangeValueForKeyOrKeys:recurse:forwardingValues:] + 664
3 Foundation 0x0000000199af4e08 -[NSKeyValueUnnestedProperty object:withObservance:didChangeValueForKeyOrKeys:recurse:forwardingValues:] + 196
4 Foundation 0x0000000199b8bc54 NSKeyValueDidChange + 200
5 Foundation 0x0000000199acde1c -[NSObject(NSKeyValueObservingPrivate) _changeValueForKeys:count:maybeOldValuesDict:maybeNewValuesDict:usingBlock:] + 684
6 Foundation 0x0000000199af7484 -[NSObject(NSKeyValueObservingPrivate) _changeValueForKey:key:key:usingBlock:] + 64
7 Foundation 0x0000000199b110e8 _NSSetObjectValueAndNotify + 284
8 AVKit 0x00000001bd3ff694 -[AVPlayerControlsViewController setPlayerController:] + 376
9 Foundation 0x0000000199acddd0 -[NSObject(NSKeyValueObservingPrivate) _changeValueForKeys:count:maybeOldValuesDict:maybeNewValuesDict:usingBlock:] + 608
10 Foundation 0x0000000199af7484 -[NSObject(NSKeyValueObservingPrivate) _changeValueForKey:key:key:usingBlock:] + 64
11 Foundation 0x0000000199b110e8 _NSSetObjectValueAndNotify + 284
12 AVKit 0x00000001bd3c6e68 -[AVPlayerView setPlaybackControlsViewController:] + 88
13 Foundation 0x0000000199b11074 _NSSetObjectValueAndNotify + 168
14 AVKit 0x00000001bd40f4b8 -[AVPlayerView _updatePlaybackControlsViewControllerIfNeeded] + 536
15 AVKit 0x00000001bd3cc0b4 -[AVPlayerView viewDidMoveToWindow] + 136
16 AppKit 0x000000019c24456c -[NSView _setWindow:] + 1788
17 AppKit 0x000000019ccce4a0 __21-[NSView _setWindow:]_block_invoke.146 + 268
18 AppKit 0x000000019c244564 -[NSView _setWindow:] + 1780
19 AppKit 0x000000019ccce4a0 __21-[NSView _setWindow:]_block_invoke.146 + 268
20 AppKit 0x000000019c244564 -[NSView _setWindow:] + 1780
...
35 AppKit 0x000000019ccce4a0 __21-[NSView _setWindow:]_block_invoke.146 + 268
36 AppKit 0x000000019c244564 -[NSView _setWindow:] + 1780
37 AppKit 0x000000019c428ec0 -[NSWindow dealloc] + 684
38 Foundation 0x000000019a1fa118 _NSKVOPerformWithDeallocatingObservable + 172
39 Foundation 0x0000000199b17404 NSKVODeallocate + 180
40 Foundation 0x0000000199b122f0 empty + 88
41 Foundation 0x0000000199af77fc dealloc + 60
42 Foundation 0x0000000199af7740 -[NSConcreteMapTable dealloc] + 76
43 AppKit 0x000000019c936e80 ___NSTouchBarFinderSetNeedsUpdateOnMain_block_invoke_2 + 1388
44 AppKit 0x000000019c2d4c4c NSDisplayCycleObserverInvoke + 168
45 AppKit 0x000000019c2d48a8 NSDisplayCycleFlush + 644
46 QuartzCore 0x00000001a0bc3f64 _ZN2CA11Transaction19run_commit_handlersE18CATransactionPhase + 120
47 QuartzCore 0x00000001a0bc2d04 _ZN2CA11Transaction6commitEv + 320
48 AppKit 0x000000019c3589d0 __62+[CATransaction(NSCATransaction) NS_setFlushesWithDisplayLink]_block_invoke + 272
49 AppKit 0x000000019cd18208 ___NSRunLoopObserverCreateWithHandler_block_invoke + 64
50 CoreFoundation 0x00000001989d187c __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 36
51 CoreFoundation 0x00000001989d1768 __CFRunLoopDoObservers + 536
52 CoreFoundation 0x00000001989d0d94 __CFRunLoopRun + 776
53 CoreFoundation 0x00000001989d0434 CFRunLoopRunSpecific + 608
54 HIToolbox 0x00000001a317419c RunCurrentEventLoopInMode + 292
55 HIToolbox 0x00000001a3173e2c ReceiveNextEventCommon + 220
...
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 AppKit 0x19c50cae8 -[NSApplication _crashOnException:] + 240
1 AppKit 0x19c358b44 __62+[CATransaction(NSCATransaction) NS_setFlushesWithDisplayLink]_block_invoke + 644
2 AppKit 0x19cd18208 ___NSRunLoopObserverCreateWithHandler_block_invoke + 64
3 CoreFoundation 0x1989d187c __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 36
4 CoreFoundation 0x1989d1768 __CFRunLoopDoObservers + 536
5 CoreFoundation 0x1989d0d94 __CFRunLoopRun + 776
6 CoreFoundation 0x1989d0434 CFRunLoopRunSpecific + 608
7 HIToolbox 0x1a317419c RunCurrentEventLoopInMode + 292
8 HIToolbox 0x1a3173e2c ReceiveNextEventCommon + 220
9 HIToolbox 0x1a3173d30 _BlockUntilNextEventMatchingListInModeWithFilter + 76
10 AppKit 0x19c22fd68 _DPSNextEvent + 660
11 AppKit 0x19ca25808 -[NSApplication(NSEventRouting) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 700
12 AppKit 0x19c22309c -[NSApplication run] + 476
13 AppKit 0x19c1fa2e0 NSApplicationMain + 880
14 Underword 0x102c099ac 0x102c08000 + 6572
15 dyld 0x19856a0e0 start + 2360
In SwiftUI we can use @AppStorage to save app settings. In my app, I have a settings view which allows the user to change various settings. Since there are many of them, it's not practical to declare a binding for each setting between the settings view and whatever other views effectively use that setting.
Is there a more convenient way to store a setting in one view and access it in another view?
I'm trying to use
@Environment(\.openDocument) private var openDocument
but it seems to only be available on macOS.
How can I open a document programmatically on iOS? My app has a custom interface for browsing and opening files, so that a tapped file should be shown in the current window, replacing the current file if it exists.
For some time now Xcode has been downloading crash reports from users of my app about crashes related to arrays. One of them looks like this:
...
Code Type: ARM-64
Parent Process: launchd [1]
User ID: 501
Date/Time: 2024-07-18 14:59:40.4375 +0800
OS Version: macOS 15.0 (24A5289h)
...
Crashed Thread: 0
Exception Type: EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x00000001045048b8
Termination Reason: Namespace SIGNAL, Code 5 Trace/BPT trap: 5
Terminating Process: exc handler [1771]
Thread 0 Crashed:
0 MyApp 0x00000001045048b8 specialized Collection.map<A>(_:) + 596
1 MyApp 0x00000001045011e4 MyViewController.validateToolbarButtons() + 648 (MyViewController.swift:742)
...
The relevant code looks like this:
class MyViewController {
func validateToolbarButtons() {
let indexes = tableView.clickedRow == -1 || tableView.selectedRowIndexes.contains(tableView.clickedRow) ? tableView.selectedRowIndexes : IndexSet(integer: tableView.clickedRow)
let items = indexes.map({ myArray[$0] })
...
}
}
The second crash looks like this:
...
Code Type: X86-64 (Native)
Parent Process: launchd [1]
User ID: 502
Date/Time: 2024-07-15 15:53:35.2229 -0400
OS Version: macOS 15.0 (24A5289h)
...
Crashed Thread: 0
Exception Type: EXC_BAD_INSTRUCTION (SIGILL)
Exception Codes: 0x0000000000000001, 0x0000000000000000
Termination Reason: Namespace SIGNAL, Code 4 Illegal instruction: 4
Terminating Process: exc handler [13244]
Thread 0 Crashed:
0 libswiftCore.dylib 0x00007ff812904fc0 _assertionFailure(_:_:flags:) + 288
1 MyApp 0x0000000101a31e04 specialized _ArrayBuffer._getElementSlowPath(_:) + 516
2 MyApp 0x00000001019d04eb MyObject.myProperty.setter + 203 (MyObject.swift:706)
3 MyApp 0x000000010192f66e MyViewController.controlTextDidChange(_:) + 190 (MyViewController.swift:166)
...
And the relevant code looks like this:
class MyObject {
var myProperty: [MyObject] {
get {
...
}
set {
let items = newValue.map({ $0.id })
...
}
}
}
What could cause such crashes? Could they be caused by anything other than concurrent access from multiple threads (which I'm quite sure is not the case here, as I only access these arrays from the main thread)?
URLResourecKey.tagNamesKey is only available on macOS, so apparently there's no way of reading or writing file tags on iOS. Why is this the case, given that file tags can be set via Finder on macOS and the Files app on iOS devices? Is there a workaround?
The sample project Filtering Network Traffic uses IPC (NSXPCConnection etc.) to send data from the network extension to the app, but the documentation for NEFilterProvider says
The sandbox prevents the Filter Data Provider extension from moving network content outside of its address space by blocking all network access, IPC, and disk write operations.
Since my network extension forwards all network traffic to the app so that the user can see it, I was wondering when the app isn’t running and the user shuts down the machine, if the network extension could write the flows it wasn’t able to forward to the app to disk, so that it could read them on the next successful connection to the app. Then almost by accident I read again the documentation and according to the quoted passage a network extension cannot write to disk, but it also cannot use IPC.
Is NSXPCConnection not considered IPC, or could the statement that it cannot write to disk be false as well?
All the threads only contain system calls. The crashed thread only contains a single call to my app's code which is main.swift:12.
What could cause such a crash?
Crash report
Every now and then my SceneKit game app crashes and I have no idea why. The SCNView has a overlaySKScene, so it might also be SpriteKit's fault.
The stack trace is
#0 0x0000000241c1470c in jet_context::set_fragment_texture(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&, jet_texture*) ()
#27 0x000000010572fd40 in _pthread_wqthread ()
Does anyone have an idea where I could start debugging this, without being able to consistently reproduce it?
On macOS, system symbols displays in a SKTexture as expected, with the correct color and aspect ratio.
But on iOS they are always displayed in black, and sometimes with slightly wrong aspect ratio.
Is there a solution to this problem?
import SpriteKit
#if os(macOS)
import AppKit
#else
import UIKit
#endif
class GameScene: SKScene {
override func didMove(to view: SKView) {
let systemImage = "square.and.arrow.up"
let width = 400.0
#if os(macOS)
let image = NSImage(systemSymbolName: systemImage, accessibilityDescription: nil)!.withSymbolConfiguration(.init(hierarchicalColor: .white))!
let scale = NSScreen.main!.backingScaleFactor
image.size = CGSize(width: width * scale, height: width / image.size.width * image.size.height * scale)
#else
let image = UIImage(systemName: systemImage)!.applyingSymbolConfiguration(.init(pointSize: width))!.applyingSymbolConfiguration(.init(hierarchicalColor: .white))!
#endif
let texture = SKTexture(image: image)
print(image.size, texture.size(), image.size.width / image.size.height)
let size = CGSize(width: width, height: width / image.size.width * image.size.height)
addChild(SKSpriteNode(texture: texture, size: size))
}
}
The following code crashes on macOS 15 Sequoia:
import Foundation
let key = NSAttributedString.Key("org.example.key")
let value = Value()
let string = NSMutableAttributedString()
string.append(NSAttributedString(string: "a", attributes: [:]))
string.append(NSAttributedString(string: "b", attributes: [key: value]))
string.append(NSAttributedString(string: "c", attributes: [:]))
string.enumerateAttribute(key, in: NSRange(location: 0, length: string.length)) { value, range, stop in
print(range)
}
class Value: Equatable, Hashable {
static func == (lhs: Value, rhs: Value) -> Bool {
return lhs === rhs
}
func hash(into hasher: inout Hasher) {
hasher.combine(ObjectIdentifier(self))
}
}
The error is
EXC_BAD_ACCESS (code=1, address=0x0)
I wanted to run it on my external macOS 14 partition to confirm that it didn't crash before updating to macOS 15, but for some reason macOS will just restart and boot again into macOS 15. So I tried with macOS 13, which I was allowed to start for some reason, and I was able to confirm that the code doesn't crash.
Is this a known issue, and is there a workaround? Removing the two lines that add the letters a and c, or just declaring class Value without conformance to Equatable, Hashable, interestingly, solves the issue.
I've been using CGWindowListCreateImage which automatically creates an image with the size of the captured window.
But SCScreenshotManager.captureImage(contentFilter:configuration:) always creates images with the width and height specified in the provided SCStreamConfiguration. I could be setting the size explicitly by reading SCWindow.frame or SCContentFilter.contentRect and multiplying the width and height by SCContentFilter.pointPixelScale , but it won't work if I want to keep the window shadow with SCStreamConfiguration.ignoreShadowsSingleWindow = false.
Is there a way and what's the best way to take full-resolution screenshots of the correct size?
import Cocoa
import ScreenCaptureKit
class ViewController: NSViewController {
@IBOutlet weak var imageView: NSImageView!
override func viewDidAppear() {
imageView.imageScaling = .scaleProportionallyUpOrDown
view.wantsLayer = true
view.layer!.backgroundColor = .init(red: 1, green: 0, blue: 0, alpha: 1)
Task {
let windows = try await SCShareableContent.excludingDesktopWindows(false, onScreenWindowsOnly: true).windows
let window = windows[0]
let filter = SCContentFilter(desktopIndependentWindow: window)
let configuration = SCStreamConfiguration()
configuration.ignoreShadowsSingleWindow = false
configuration.showsCursor = false
configuration.width = Int(Float(filter.contentRect.width) * filter.pointPixelScale)
configuration.height = Int(Float(filter.contentRect.height) * filter.pointPixelScale)
print(filter.contentRect)
let windowImage = try await SCScreenshotManager.captureImage(contentFilter: filter, configuration: configuration)
imageView.image = NSImage(cgImage: windowImage, size: CGSize(width: windowImage.width, height: windowImage.height))
}
}
}
A customer of mine reported that since updating to macOS 15 they aren't able to use my app anymore, which performs a deep scan of selected folders by recursively calling getattrlistbulk. The problem is that the app apparently keeps scanning forever, with the number of scanned files linearly increasing to infinity.
This happens for some folders on a SMB volume.
The customer confirmed that they can reproduce the issue with a small sample app that I attach below. At first, I created a sample app that only scans the contents of the selected folder without recursively scanning the subcontents, but the issue didn't happen anymore, so it seems to be related to recursively calling getattrlistbulk.
The output of the sample app on the customer's Mac is similar to this:
start scan /Volumes/shares/Backup/Documents level 0 fileManagerCount 2847
continue scan /Volumes/shares/Backup/Documents new items 8, sum 8, errno 34
/Volumes/shares/Backup/Documents/A.doc
/Volumes/shares/Backup/Documents/B.doc
...
continue scan /Volumes/shares/Backup/Documents new items 7, sum 1903, errno 0
/Volumes/shares/Backup/Documents/FKV.pdf
/Volumes/shares/Backup/Documents/KFW.doc
/Volumes/shares/Backup/Documents/A.doc
/Volumes/shares/Backup/Documents/B.doc
...
which shows that counting the number of files in the root folder by using
try FileManager.default.contentsOfDirectory(atPath: path).count
returns 2847, while getattrlistbulk lists about 1903 files and then starts listing the files from the beginning, not even between repeated calls, but within a single call.
What could this issue be caused by?
(The website won't let me attach .swift files, so I include the source code of the sample app as a text attachment.)
ViewController.swift
Even when the action is run on the main thread, the following code causes a crash on iOS, but not on macOS. The game launches with a simple yellow rectangle, and when it finishes fading out and should be removed from the overlay scene, the app crashes.
The code can be pasted into the file GameController.swift of Xcode's default project for Multiplatform macOS and iOS game.
import SceneKit
import SpriteKit
@MainActor
class GameController: NSObject {
let scene: SCNScene
let sceneRenderer: SCNSceneRenderer
init(sceneRenderer renderer: SCNSceneRenderer) {
sceneRenderer = renderer
scene = SCNScene(named: "Art.scnassets/ship.scn")!
super.init()
sceneRenderer.scene = scene
renderer.overlaySKScene = SKScene(size: CGSize(width: 500, height: 500))
DispatchQueue.main.async {
let node = SKShapeNode(rect: CGRect(x: 100, y: 100, width: 100, height: 100))
node.fillColor = .yellow
node.run(.sequence([
.fadeOut(withDuration: 1),
.removeFromParent()
]))
renderer.overlaySKScene!.addChild(node)
}
}
}
The Xcode console shows this stacktrace:
*** Assertion failure in -[UIApplication _performAfterCATransactionCommitsWithLegacyRunloopObserverBasedTiming:block:], UIApplication.m:3246
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Call must be made on main thread'
*** First throw call stack:
(
0 CoreFoundation 0x00000001804ae0f8 __exceptionPreprocess + 172
1 libobjc.A.dylib 0x0000000180087db4 objc_exception_throw + 56
2 Foundation 0x0000000180d17058 _userInfoForFileAndLine + 0
3 UIKitCore 0x00000001853cf678 -[UIApplication _performAfterCATransactionCommitsWithLegacyRunloopObserverBasedTiming:block:] + 376
4 UIKitCore 0x000000018553f7a0 -[_UIFocusUpdateThrottle scheduleProgrammaticFocusUpdate] + 300
5 UIKitCore 0x0000000184e2e22c -[UIFocusSystem _requestFocusUpdate:] + 548
6 UIKitCore 0x0000000184e2dfa4 -[UIFocusSystem requestFocusUpdateToEnvironment:] + 76
7 UIKitCore 0x0000000184e2e864 -[UIFocusSystem _focusEnvironmentWillDisappear:] + 408
8 SpriteKit 0x00000001a3d472f4 _ZL12_removeChildP6SKNodeS0_P7SKScene + 240
9 SpriteKit 0x00000001a3d473b0 -[SKNode removeChild:] + 80
10 SpriteKit 0x00000001a3d466b8 -[SKNode removeFromParent] + 128
11 SpriteKit 0x00000001a3d1678c -[SKRemove updateWithTarget:forTime:] + 64
12 SpriteKit 0x00000001a3d1b740 _ZN11SKCSequence27cpp_updateWithTargetForTimeEP7SKCNoded + 84
13 SpriteKit 0x00000001a3d20e3c _ZN7SKCNode6updateEdf + 156
14 SpriteKit 0x00000001a3d20f20 _ZN7SKCNode6updateEdf + 384
15 SpriteKit 0x00000001a3d26fb8 -[SKScene _update:] + 464
16 SpriteKit 0x00000001a3cf3168 -[SKSCNRenderer _update:] + 80
17 SceneKit 0x000000019c932bf0 -[SCNMTLRenderContext renderSKSceneWithRenderer:overlay:atTime:] + 60
18 SceneKit 0x000000019c9ebd98 -[SCNRenderer _drawOverlaySceneAtTime:] + 204
19 SceneKit 0x000000019cb1a1c0 _ZN3C3D11OverlayPass7executeERKNS_10RenderArgsE + 60
20 SceneKit 0x000000019c8e05ec _ZN3C3D13__renderSliceEPNS_11RenderGraphEPNS_10RenderPassERtRKNS0_9GraphNodeERPNS0_5StageENS_10RenderArgsEbRPU27objcproto16MTLCommandBuffer11objc_object + 2660
21 SceneKit 0x000000019c8e18ac _ZN3C3D11RenderGraph7executeEv + 3808
22 SceneKit 0x000000019c9ed26c -[SCNRenderer _renderSceneWithEngineContext:sceneTime:] + 756
23 SceneKit 0x000000019c9ed544 -[SCNRenderer _drawSceneWithNewRenderer:] + 208
24 SceneKit 0x000000019c9ed9fc -[SCNRenderer _drawScene:] + 40
25 SceneKit 0x000000019c9edce4 -[SCNRenderer _drawAtTime:] + 500
26 SceneKit 0x000000019ca87950 -[SCNView _drawAtTime:] + 368
27 SceneKit 0x000000019c943b74 __83-[NSObject(SCN_DisplayLinkExtensions) SCN_setupDisplayLinkWithQueue:screen:policy:]_block_invoke + 44
28 SceneKit 0x000000019ca50600 -[SCNDisplayLink _displayLinkCallbackReturningImmediately] + 132
29 libdispatch.dylib 0x000000010239173c _dispatch_client_callout + 16
30 libdispatch.dylib 0x0000000102394c14 _dispatch_continuation_pop + 756
31 libdispatch.dylib 0x00000001023aa4e0 _dispatch_source_invoke + 1736
32 libdispatch.dylib 0x00000001023997f0 _dispatch_lane_serial_drain + 340
33 libdispatch.dylib 0x000000010239a774 _dispatch_lane_invoke + 420
34 libdispatch.dylib 0x00000001023a71a8 _dispatch_root_queue_drain_deferred_wlh + 324
35 libdispatch.dylib 0x00000001023a6604 _dispatch_workloop_worker_thread + 488
36 libsystem_pthread.dylib 0x000000010242bb74 _pthread_wqthread + 284
37 libsystem_pthread.dylib 0x000000010242a934 start_wqthread + 8
)
libc++abi: terminating due to uncaught exception of type NSException
Am I doing something wrong?
When I create a modal segue to a navigation controller in a storyboard, the navigation bar buttons appear correctly. But when trying to recreate this programmatically, no buttons appear:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let button = UIButton(type: .infoLight, primaryAction: UIAction(handler: { _ in
self.present(UINavigationController(rootViewController: ModalViewController()), animated: true)
}))
button.frame.origin = CGPoint(x: 100, y: 100)
view.addSubview(button)
}
}
class ModalViewController: UIViewController {
override func loadView() {
let button = UIBarButtonItem(title: "button")
button.primaryAction = UIAction(handler: { action in
})
button.style = .done
navigationItem.title = "title"
navigationItem.rightBarButtonItem = button
view = UITableView()
}
}
What am I doing wrong?