Post

Replies

Boosts

Views

Activity

Reply to What is difference between lineFragmentRect and lineFragmentUsedRect in TextKit?
After few hours later, I cloud solve this question by myself. These are difference that my screenshots claim: ・lineFragmentRect ・lineFragmentUsedRect Please look at the right edge of red borders. These maxX and width are not equal. Assuming from this behavior, I understand that lineFragmentRect is rect for proposing line fragment in glyph layout process, and lineFragmentUsedRect is actual rect that the glyphs are filled, considering word wrap and hyphen factor. ・Code I used for investigation.     func addLineFragmentBorder(of text: String) {         let range = (textView.text as NSString).range(of: text)         let glyphRange = textView.layoutManager.glyphRange(forCharacterRange: range, actualCharacterRange: nil) // You can try the difference by changing `lineFragmentUsedRect` to `lineFragmentRect`.         let lineRect = textView.layoutManager.lineFragmentUsedRect(forGlyphAt: glyphRange.location, effectiveRange: nil)         let borderLayer = CALayer()         borderLayer.frame = .init(x: lineRect.minX, y: lineRect.minY + textView.textContainerInset.top, width: lineRect.width, height: lineRect.height)         borderLayer.borderColor = UIColor.red.cgColor         borderLayer.borderWidth = 2         borderLayer.backgroundColor = UIColor.clear.cgColor         textView.layer.addSublayer(borderLayer)     }
Oct ’21
Reply to Can an App detect a subscription's cancellation in itself?
Fortunately, I found a solution! A @MainActor static func showManageSubscriptions(in scene: UIWindowScene) async throws suspends the task until the user selects "Done" or "Cancel" in the manage subscription screen, so you can manually check the updated state in the next line. Task {     do { // The method suspends the execution until the user selects "Done" or "Cancel"         try await AppStore.showManageSubscriptions(in: view.window!.windowScene!) // The line is executed after dismissing the screen. You can check the latest state of your app's subscription, then update your UI.         await checkAndUpdateAppSubscriptionStateI()      } catch let storeKitEerror as StoreKitError { // Error handling      } }
Jul ’22
Reply to New NSSearchToolbarItem in Mac Catalyst
Good news for you! Today, iPadOS with catalyst automatically translates navigationItem.searchController to AppKit native NSSearchToolbarItem. (However, only automatic-translation support AppKit native component. It is not available with manual NSToolbar. Please check the wwdc session. https://developer.apple.com/videos/play/wwdc2022/10076/ A public sample project is here https://developer.apple.com/documentation/uikit/app_and_environment/supporting_desktop-class_features_in_your_ipad_app.
Aug ’22
Reply to BUG: Broken NavigationStack when .bottomBar and back-half-swipe
My Workaround func bottomBarAlternative<V>(@ViewBuilder _ content: () -> V) -> some View where V : View { self.safeAreaInset(edge: .bottom) { HStack { content() } .labelStyle(.iconOnly) .imageScale(.large) .padding() .frame(maxHeight: 50) .background(Material.ultraThinMaterial) .overlay { VStack(spacing: 0) { Divider() Spacer() } } .accessibilityElement(children: .contain) .accessibilityLabel("Toolbar") } }
Oct ’23
Reply to How much time is AppIntent.perform() method given?
In addition to my testing that 20~30 seconds are given to perform(), I've found an apple official comment about how much perform()method is given in Responding to the Action button on Apple Watch Ultra Then, implement your intent’s perform() method. The system calls this method when anything triggers the intent. In your implementation, you have 30 seconds to start a workout session and return a successful value. If you don’t start a workout session in that time, the system displays an error message, but the app remains in the foreground. People can start a workout session directly from the app, but without a session, the app goes to the background the next time they drop their wrist In the documentation, Apple says workout intent's perform() has 30 seconds.
Mar ’24
Reply to Xcode NSMetaDataQuery error on device running IOS 17.5 - [ERROR] couldn't fetch remote operation IDs
@Onymacris, I could solve the problem! Error messages are still shown, but I guess that the query and error messages are separate, and not related problem. I've moved calling my startQuery method from RootView.task to RootView.onAppear. struct MyApp : App { var body: some Scene { WindowGroup { RootView() .onAppear { startQuery() } } } } This works fine! Only delaying the call may solve the query problem. In Apple official sample, it starts query at viewDidLoad(). It is not so fast timing.
Aug ’24
Reply to Any workaround for expanding a large category in FamilyActivityPicker?
For people who want to show an alert as soon as possible after the FamilyActivityPicker has crashed, I'll share my workaround ! Workaround struct MyView : View { let stateUpdateTimer = Timer.publish(every: 1, on: .main, in: .common).autoconnect() @State private var updateFlag: Bool = false var body : some View { ZStack { Text(verbatim: "A") // This should not be empty. .foregroundStyle(.clear) .accessibilityHidden(true) .opacity(updateFlag ? 1 : 0) ContentUnavailableView(...) FamilyActivityPicker(...) } .onReceive(stateUpdateTimer) { _ in updateFlag.toggle() } } } Description At first glance, it looks like the FamilyActivityPicker has frozen, but I realized that it simply doesn’t redraw. Therefore, if there is an event that triggers a redraw, it will quickly transition to a transparent after the crash. The above code forces a view update every second by toggling the opacity of a view that is completely irrelevant to the user. This let the FamilyActivityPicker transition to a transparent and immediately show an alert in ZStack. Good Points This workaround doesn't touch any private API and private class. It relies only on public APIs and minimal code, therefore It will continue to work without issues even if the internal implementation is changed in the future.
Sep ’24