I am trying to seamlessly transition a view from one view controller and have it "jump" into a sheet.
Apple does this in their widget picker for example when you add one of the top widgets.
Based on all the documentation I've read, the most common approach to this is to snapshot the area/view that you are trying to seamlessly transition in the presented view controller (the place where the item is coming from. And then have that snapshot translate across into where it should be in the layout of the presenting view controller.
func makeAnimatorIfNeeded(
using transitionContext: UIViewControllerContextTransitioning
) -> UIViewPropertyAnimator {
if let animator = animator {
return animator
}
// Presentation animation
let animator = UIViewPropertyAnimator(
duration: 0.5,
timingParameters: UISpringTimingParameters(dampingRatio: 1.0)
)
guard let fromVC = transitionContext.viewController(forKey: .from),
let toVC = transitionContext.viewController(forKey: .to)
else {
transitionContext.completeTransition(false)
return animator
}
/// !IMPORTANT: For some weird reason, accessing the views of the view controller
/// directly, like `fromVC.view` or `toVC.view` will break the sheet transition and gestures.
/// Instead, use the `view(forKey:)` method of the `transitionContext` to get the views.
let fromView = transitionContext.view(forKey: .from)
let toView = transitionContext.view(forKey: .to)
let containerView = transitionContext.containerView
let fromFrame = transitionContext.viewController(forKey: .from).map { transitionContext.finalFrame(for: $0) } ?? containerView.bounds
let toFrame = transitionContext.viewController(forKey: .to).map { transitionContext.finalFrame(for: $0) } ?? containerView.bounds
// Calculate the frame of sourceView relative to fromVC.view to capture the correct snapshot area.
let snapshotFrameInFromVC = sourceView?.convert(sourceView?.frame ?? .zero, to: fromVC.view) ?? containerView.frame
// Calculate the frame of sourceView relative to containerView to position the snapshot correctly.
let snapshotFrameInContainer = sourceView?.convert(sourceView?.frame ?? .zero, to: containerView) ?? containerView.frame
let snapshot: UIView?
if isPresenting {
// Create a snapshot of fromVC.view from the defined area (snapshotFrameInFromVC).
let originalColor = fromVC.view.backgroundColor
fromVC.view.backgroundColor = .clear
snapshot = fromVC.view.resizableSnapshotView(from: snapshotFrameInFromVC,
afterScreenUpdates: true,
withCapInsets: .zero)
fromVC.view.backgroundColor = originalColor
// Position the snapshot correctly within the snapshot container
snapshot?.frame = snapshotFrameInContainer
toView?.frame = toFrame
toView?.transform = CGAffineTransform(translationX: 0, y: containerView.frame.size.height)
toView?.layoutIfNeeded()
if let fromView {
containerView.addSubview(fromView)
}
if let toView {
containerView.addSubview(toView)
containerView.addSubview(snapshot ?? UIView())
}
let toViewCenter = CGPoint(
x: toVC.view.bounds.midX,
y: toVC.view.bounds.midY + 55
)
let gestureVelocity = CGPoint(x: 0, y: -5000)
animator.addAnimations {
Wave.animate(
withSpring: self.animatedSpring,
mode: .animated,
gestureVelocity: gestureVelocity
) {
snapshot?.animator.frame.size = CGSize(width: 204, height: 204) // Important to animate first
snapshot?.animator.center = toViewCenter
} completion: { finished, retargeted in
print("finished: \(finished), retargeted: \(retargeted)")
}
toView?.transform = CGAffineTransform.identity
}
animator.addCompletion { animatingPosition in
switch animatingPosition {
case .end:
snapshot?.removeFromSuperview()
transitionContext.completeTransition(true)
default:
transitionContext.completeTransition(false)
}
}
} else {
// Transitioning view is fromView
if let toView {
containerView.addSubview(toView)
}
if let fromView {
containerView.addSubview(fromView)
}
animator.addAnimations {
fromView?.transform = CGAffineTransform(translationX: 0, y: containerView.frame.size.height)
}
animator.addCompletion { animatingPosition in
switch animatingPosition {
case .end:
transitionContext.completeTransition(true)
default:
transitionContext.completeTransition(false)
}
}
}
self.animator = animator
return animator
}
I can pull this off seamlessly if the animation involves a simple movement from A to B.
But if I try to resize the snapshot as well, the snapshot becomes pixelated and low quality (I assume this is because the snapshot is literally a small screenshot and I'm stretching it from 56x56 to 204x204).
Is there another way that I'm overlooking to pull this off without a snapshot? Or is there a way I can resize the snapshot without losing quality?
Here is the animator code, it works great without the sizing so this should help future people looking to replicate the same effect anyways.
UIKit
RSS for tagConstruct and manage graphical, event-driven user interfaces for iOS or tvOS apps using UIKit.
Post
Replies
Boosts
Views
Activity
With the upcoming launch of Apple Intelligence and Writing Tools, we've been forced to migrate our text editing app to TextKit 2. As soon as we released the update, we immediately got complaints about incorrect selection behaviour, where the user would tap a word to begin editing, but the caret would be shown in an undefined location, often dozens of paragraphs below the selected content.
To reproduce:
Create a UITextView backed by a standard TextKit 2 stack and a large amount of text (50,000+ words) - see sample project below
Scroll quickly through the text view (at least 20% of the way down)
Tap once to select a position in the document.
Expected:
The caret appears at the location the user tapped, and UITextView.selectedRange is the range of the text at the location of the tap. This is the behaviour of TextKit 1 based UITextViews.
Actual:
The caret is positioned at an undefined location (often completely off screen), and the selectedRange is different to the range at the location of the tap, often by several thousand. There is no pattern to the magnitude of the discrepancy.
This incorrect behaviour occurs consistently in the sample project on the simulator, but you may need to hide the keyboard by pulling down, then repeat steps 2-3 a few times. This happens on iPhone and iPad, and on iOS 17, 18, and 18.1.
Do you have any insight into why this might be happening or how to work around this issue?
Sample code is here: https://github.com/nathantesler/textkit2-issue/tree/master
UITextView changed the sequence of views and on the top UIView. As a result in the custom gesture class in "touchesBegan" method, this code brings me "let touchedView = touches.first?.view" type of view UIView but it must be my own custom class type.
How can I get a tapped type of view? Help please
override func touchesBegan(_ touches: Set, with event: UIEvent) {
super.touchesBegan(touches, with: event)
let touchedView = touches.first?.view
}
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Reason: *** -[__NSArrayM insertObject:atIndex:]: object cannot be nil
Termination Reason: SIGNAL 6 Abort trap: 6
Terminating Process:XXXX [XXXX]
Triggered by Thread: 0
Application Specific Information:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil
UserInfo:(null)'
Last Exception Backtrace:
0 CoreFoundation 0x1930d108c __exceptionPreprocess + 164 (NSException.m:249)
1 libobjc.A.dylib 0x1903d32e4 objc_exception_throw + 88 (objc-exception.mm:356)
2 CoreFoundation 0x193070424 -[__NSArrayM insertObject:atIndex:] + 1276 (NSArrayM.m:164)
3 UIKitCore 0x195b6249c 0x195818000 + 3450012
4 UIKitCore 0x1958c9070 0x195818000 + 725104
5 UIKitCore 0x195899c3c _UIGestureEnvironmentUpdate + 2488 (UIGestureEnvironment.m:192)
6 UIKitCore 0x19598f914 -[UIGestureEnvironment _deliverEvent:toGestureRecognizers:usingBlock:] + 336 (UIGestureEnvironment.m:843)
7 UIKitCore 0x195b2ff18 -[UIGestureEnvironment _updateForEvent:window:] + 188 (UIGestureEnvironment.m:810)
8 UIKitCore 0x195b2f2fc -[UIWindow sendEvent:] + 2948 (UIWindow.m:3627)
11 UIKitCore 0x1959c39b4 -[UIApplication sendEvent:] + 376 (UIApplication.m:12948)
13 UIKitCore 0x1959c3ee0 __dispatchPreprocessedEventFromEventQueue + 1048 (UIEventDispatcher.m:2641)
14 UIKitCore 0x1959cdcc4 __processEventQueue + 5696 (UIEventDispatcher.m:2999)
15 UIKitCore 0x1958c6270 updateCycleEntry + 160 (UIEventDispatcher.m:133)
16 UIKitCore 0x1958c3fe8 _UIUpdateSequenceRun + 84 (_UIUpdateSequence.mm:136)
17 UIKitCore 0x1958c3c38 schedulerStepScheduledMainSection + 172 (_UIUpdateScheduler.m:1171)
18 UIKitCore 0x1958c4bac runloopSourceCallback + 92 (_UIUpdateScheduler.m:1334)
19 CoreFoundation 0x1930a4088 CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 28 (CFRunLoop.c:1950)
20 CoreFoundation 0x1930a401c __CFRunLoopDoSource0 + 176 (CFRunLoop.c:1994)
21 CoreFoundation 0x1930a1b08 __CFRunLoopDoSources0 + 244 (CFRunLoop.c:2031)
22 CoreFoundation 0x1930a0d04 __CFRunLoopRun + 840 (CFRunLoop.c:2949)
23 CoreFoundation 0x1930a05b8 CFRunLoopRunSpecific + 572 (CFRunLoop.c:3414)
24 GraphicsServices 0x1deb361c4 GSEventRunModal + 164 (GSEvent.c:2196)
25 UIKitCore 0x195bf65f0 -[UIApplication _run] + 816 (UIApplication.m:3820)
26 UIKitCore 0x195ca510c UIApplicationMain + 340 (UIApplication.m:5472)
27 XXXX 0x104744880 main + 200 (main.m:41)
28 dyld 0x1b8873d34 start + 2724 (dyldMain.cpp:1334)
I'm using UIKit to display a long list of large images inside a SwiftUI ScrollView and LazyHStack using UIViewControllerRepresentable. When an image is loaded, I'm using SDWebImage to load the image from the disk.
As the user navigates through the list and continues to load more images, more memory is used and is never cleared, even as the images are unloaded by the LazyHStack. Eventually, the app reaches the memory limit and crashes. This issue persists if I load the image with UIImage(contentsOfFile: ...) instead of SDWebImage.
How can I free the memory used by UIImage when the view is removed?
ScrollView(.horizontal, showsIndicators: false) {
LazyHStack(spacing: 16) {
ForEach(allItems) { item in
TestImageDisplayRepresentable(item: item)
.frame(width: geometry.size.width, height: geometry.size.height)
.id(item.id)
}
}
.scrollTargetLayout()
}
import UIKit
import SwiftUI
import SDWebImage
class TestImageDisplay: UIViewController {
var item: TestItem
init(item: TestItem) {
self.item = item
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
imageView.center = view.center
view.addSubview(imageView)
imageView.sd_setImage(with: item.imageURL, placeholder: nil)
}
}
struct TestImageDisplayRepresentable: UIViewControllerRepresentable {
var item: TestItem
func makeUIViewController(context: Context) -> TestImageDisplay {
return TestImageDisplay(item: item)
}
func updateUIViewController(_ uiViewController: TestImageDisplay, context: Context) {
uiViewController.item = item
}
}
is now broken. (but definitely worked when I originally wrote my Document-based app)
It's been a few years.
DocumentBrowserViewController's delegate implements the following func.
func documentBrowser(_ controller: UIDocumentBrowserViewController, didRequestDocumentCreationWithHandler importHandler: @escaping (URL?, UIDocumentBrowserViewController.ImportMode) -> Void) {
let newDocumentURL: URL? = Bundle.main.url(forResource: "blankFile", withExtension: "trtl2")
// Make sure the importHandler is always called, even if the user cancels the creation request.
if newDocumentURL != nil {
importHandler(newDocumentURL, .copy)
} else {
importHandler(nil, .none)
}
}
When I tap the + in the DocumentBrowserView, the above delegate func is called (my breakpoint gets hit and I can step through the code) newDocumentURL is getting defined successfully and
importHandler(newDocumentURL, .copy)
gets called, but returns the following error:
Optional(Error Domain=com.apple.DocumentManager Code=2 "No location available to save “blankFile.trtl2”." UserInfo={NSLocalizedDescription=No location available to save “blankFile.trtl2”., NSLocalizedRecoverySuggestion=Enable at least one location to be able to save documents.})
This feels like something new I need to set up in the plist, but so far haven't been able to discover what it is.
perhaps I need to update something in info.plist? perhaps one of:
CFBundleDocumentTypes
UTExportedTypeDeclarations
Any guidance appreciated.
thanks :-)
I have created a custom logo in the SFSymbols 6.1 app and exported it as SVG.
clock.arrow.trianglehead.clockwise.rotate.90.svg
The icon consists of two layers and I want them to animate by layer. This works for the wiggle effect (the two layers are moving independently), but not for the rotate effect (the logo moves as a whole). Why? This is my code:
let imageView = UIImageView()
imageView.preferredSymbolConfiguration = UIImage.SymbolConfiguration(scale: .large)
imageView.image = UIImage(named: "clock.arrow.trianglehead.clockwise.rotate.90", in: nil, with: nil)
imageView.translatesAutoresizingMaskIntoConstraints = false
let imageView2 = UIImageView()
imageView2.preferredSymbolConfiguration = UIImage.SymbolConfiguration(scale: .large)
imageView2.image = UIImage(named: "clock.arrow.trianglehead.clockwise.rotate.90", in: nil, with: nil)
imageView2.translatesAutoresizingMaskIntoConstraints = false
imageView.addSymbolEffect(.rotate.byLayer, options: .repeat(.continuous));
imageView2.addSymbolEffect(.wiggle.byLayer, options: .repeat(.continuous));
view.addSubview(imageView)
view.addSubview(imageView2)
NSLayoutConstraint.activate([
imageView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
imageView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
imageView2.centerXAnchor.constraint(equalTo: view.centerXAnchor),
imageView2.topAnchor.constraint(equalTo: imageView.bottomAnchor, constant: 40),
])
In iOS 18, when navigating from Page A (with a red navigation bar background color) to Page B, and Page B hides the navigation bar, upon returning to Page A, the background color of the navigation bar appears white (seemingly transparent).
The navigation bar background for the share button should be red.
We are currently combining AutoLayout and StackView to structure our cells, and we’re using UICollectionViewCompositionalLayout to set up sections. Additionally, we’re utilizing UICollectionViewDiffableDataSource to manage the data source. On the home screen, we display cells in a multi-section layout.
In the main screen, we support infinite scrolling and use a paging method that fetches 10 items at a time from the API. As we fetch and render more data, the number of displayed cells increases. However, we’ve noticed that as the number of displayed cells grows, the UI freezes during the process of fetching and rendering more data.
We suspect that the issue lies in the configuration of UICollectionViewCompositionalLayout. When data is fetched through paging, the data is applied to the CollectionViewDiffableDataSource, and during the process of displaying it on the screen, the method that configures the UICollectionViewCompositionalLayout layout is called. The problem here is that when 10 cells are displayed on the screen and we fetch more data through paging and add 10 more cells, the layout calculation is redone for all 20 cells. In other words, the UICollectionViewCompositionalLayout layout configuration occurs a total of 20 times.
Because of this, it seems that the UI freezing issue occurs as the number of cells increases.
What steps can we take to resolve this problem? We have attached the relevant code for your reference.
private lazy var collectionView = UICollectionView(
frame: .zero,
collectionViewLayout: self.createCollectionViewLayout()
)
private func createCollectionViewLayout() -> UICollectionViewLayout {
let layout = UICollectionViewCompositionalLayout { [weak self] sectionIndex, _ in
guard let self, self.dataSource.snapshot().sectionIdentifiers.isEmpty == false
else { return LayoutProvider.emptySection() }
private func applyRefreshSnapshot(with sections: [PlateViewSection]) {
var snapshot = self.dataSource.snapshot()
snapshot.deleteAllItems()
snapshot.appendSections(sections)
sections.forEach { section in
snapshot.appendItems(section.items, toSection: section)
}
self.dataSource.apply(snapshot, animatingDifferences: false)
}
let sectionIdentifier = self.dataSource.snapshot().sectionIdentifiers[safe: sectionIndex]
let analyticsScreen = self.payload.analyticsScreen
switch sectionIdentifier?.module {
case let .tabOutlined(_, reactor):
if self.tabOutlinedView == nil {
let tabOutlinedView = self.dependency.tabOutlinedViewFactory.create(
payload: .init(
reactor: reactor,
collectionView: self.collectionView,
analyticsScreen: analyticsScreen,
currentDisplayDepthObserver: .init { event in
guard let depth = event.element else { return }
self.currentLayoutHeaderTabDepth = depth
},
selectedTabItemObserver: .init { [weak self] event in
guard let (tab, isPrimaryTabClick) = event.element else { return }
var queryParams: [String: String]?
if isPrimaryTabClick == false {
guard let currentState = self?.reactor?.currentState else { return }
let currentSelectedQueryParams = self?.dependency.userDefaults
.dictionary(forKey: Keys.PlateParamsKeys.brandQueryParams) as? [String: String]
queryParams = currentSelectedQueryParams ?? currentState.defaultQueryParams
}
self?.scrollCollectionViewToTop()
self?.collectionView.viewWithTag(
QueryToggleModuleCell.Metric.optionsMenuViewTag
)?.removeFromSuperview()
self?.reactor?.action.onNext(.refreshWithParams(
tabParams: tab?.params,
queryParams: queryParams
))
}
)
)
self.view.addSubview(tabOutlinedView)
tabOutlinedView.snp.makeConstraints { make in
make.top.leading.trailing.equalToSuperview()
}
self.view.layoutIfNeeded()
self.tabOutlinedView = tabOutlinedView
self.tabOutlinedView?.emitInitializeAction()
}
return LayoutProvider.emptySection()
case let .carouselOneRowBrand(module, _):
let section = self.dependency.layoutProvider.createLayoutSection(module: module)
section.visibleItemsInvalidationHandler = { [weak self] _, _, _ in
guard let self else { return }
self.emitFetchLikedAction(module: module, sectionIndex: sectionIndex)
}
return section
case let .queryToggle(module):
return self.dependency.layoutProvider.createLayoutSection(module: module)
case .loadingIndicator:
return LayoutProvider.loadingIndicatorSection()
case let .space(module):
return self.dependency.layoutProvider.createLayoutSection(module: module)
case let .noResult(module):
return self.dependency.layoutProvider.createLayoutSection(module: module)
case let .buttonViewAll(module):
return self.dependency.layoutProvider.createLayoutSection(module: module)
case .footer:
return LayoutProvider.footerSection()
default:
return LayoutProvider.emptySection()
}
}
return layout
}
private func applyAppendSnapshot(with sections: [PlateViewSection]) {
var snapshot = self.dataSource.snapshot()
// loadingIndicator section delete
let sectionsToDelete = snapshot.sectionIdentifiers.filter { section in
section.module == .loadingIndicator
}
snapshot.deleteSections(sectionsToDelete)
snapshot.appendSections(sections)
sections.forEach { section in
snapshot.appendItems(section.items, toSection: section)
}
self.dataSource.apply(snapshot, animatingDifferences: false)
}
I'm working on an iOS app that integrates with Spotify for authentication. I’m facing a problem where the app doesn’t handle URL schemes and app state transitions properly. Specifically, when Spotify redirects back to my app, it either doesn’t handle the URL correctly or doesn’t transition between states as expected. The authorization for spotify is successful, then my app reopens and nothing happens after that.
Expected Behavior: When Spotify redirects to my app, it should correctly handle the URL and process authentication parameters.
Actual Behavior: Even with URL handling code commented out, the app reopens from Spotify, which suggests a possible issue with how URL schemes or app state transitions are managed. The app’s state transitions don’t seem to be handled as expected.
Troubleshooting Steps Taken:
Verified URL schemes and redirect URIs.
Implemented application(_:open:options:) for URL handling.
Tested various app states (foreground, background, suspended).
//This code should open my app using the URL from spotify but this code never triggers and yet my app opens anyways//
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
print("Received URL: (url.absoluteString)")
handleSpotifyURL(url)
return true
}
private func handleSpotifyURL(_ url: URL) {
// URL handling logic
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Logic for when the app becomes active
}
//Using latest software for xcode, testing on iphone 14 with up to date software and up to date spotify
As mentioned - have ensure that my info plist is configured correctly, that spotify authorizes correctly, that the redirect URI is correct in my code and on spotify for developers.
From the testing I've done I imagine there is something wrong with how my app gets opened vs how it should get opened with the callback URL triggering func application(_ app: UIApplication, open url: URL, options:....
What I am expecting is that when spotify triggers the callback url - my app reopens with the above function and from there can retrieve the access token etc.
I used tabBarItem & UITabBarController create a demo app.
then I set every pages backgroudcolor as red.
when I change to every pages withing the tabBarItem at bottom. the page's background color highlight every time.
I don't know why. Is this the new UIKit's bug?
Watch OS11 My recording play gets paused when watch I turned down.
It was not happening in previous versions.
In my app I recorded my recording.
And When I play it in my app,
it was playing good in debug mode(when Xcode is connected) could not debug.
Otherwise, it was automatically paused(when my wrist is down or inactivity time is elapsed)
I want it to be continued.
I implemented the view displaying the video on a UIScrollView, but the UI freezes during the zooming action.
The clock and status bar both freeze, but interestingly, if I touch the tab bar, everything starts working again after a few seconds.
I am experiencing this issue only on an iPhone 12 Pro running iOS 16.5.1, but it doesn’t occur on other phones. I would like to know if this is an OS bug.
Has anyone else experienced the same issue?
1、 hook respondsToSelector: 接口,比如 hook 后的接口名字为 yy_respondsToSelector: 2、在 yy_respondsToSelector 中使用传入的参数 aSelector。示例代码如下:
(BOOL) yy_respondsToSelector:(SEL)aSelector { if ([self yy_respondsToSelector:aSelector]) { return YES; }
if ([self.selectorNameArray containsObject:NSStringFromSelector(aSelector)]) { return YES; } return NO;
}
2、在自定义 UIViewController,比如 YYViewController,实现下述代码
(void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated];
NSMutableArray *vcs = [[NSMutableArray alloc]init]; [vcs addObject:[[UIViewController alloc] init] ]; [vcs addObject:[[UIViewController alloc] init] ]; self.navigationController.viewControllers = vcs;
}
3、当页面 YYViewController加载并执行 viewDidAppear 时候, App 一定会出现崩溃,因为 aSelector 是一个非法指针,访问就会崩溃
Hook respondsToSelector: interface. For example, the name of the hooked interface is yy_respondsToSelector: 2. Use the passed parameter aSelector in yy_respondsToSelector. The sample code is as follows:
(BOOL) yy_respondsToSelector:(SEL)aSelector { if ([self yy_respondsToSelector:aSelector]) { return YES; }
if ([self.selectorNameArray containsObject:NSStringFromSelector(aSelector)]) { return YES; } return NO;
}
2. In a custom UIViewController, such as YYViewController, implement the following code
(void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated];
NSMutableArray *vcs = [[NSMutableArray alloc]init]; [vcs addObject:[[UIViewController alloc] init] ]; [vcs addObject:[[UIViewController alloc] init] ]; self.navigationController.viewControllers = vcs;
}
3. When the page YYViewController is loaded and viewDidAppear is executed, App There will definitely be a crash, because aSelector is an illegal pointer, and access will crash
1、 hook respondsToSelector: 接口,比如 hook 后的接口名字为 yy_respondsToSelector:
2、在 yy_respondsToSelector 中使用传入的参数 aSelector。示例代码如下:
(BOOL) yy_respondsToSelector:(SEL)aSelector {
if ([self yy_respondsToSelector:aSelector]) {
return YES;
}
if ([self.selectorNameArray containsObject:NSStringFromSelector(aSelector)]) {
return YES;
}
return NO;
}
2、在自定义 UIViewController,比如 YYViewController,实现下述代码
(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSMutableArray *vcs = [[NSMutableArray alloc]init];
[vcs addObject:[[UIViewController alloc] init] ];
[vcs addObject:[[UIViewController alloc] init] ];
self.navigationController.viewControllers = vcs;
}
3、当页面 YYViewController加载并执行 viewDidAppear 时候, App 一定会出现崩溃,因为 aSelector 是一个非法指针,访问就会崩溃
My project use manual reference counting and crash with UIAlertController when touch to Action Button:
UIAlertController alert = [[UIAlertController
alertControllerWithTitle:@"fsđs"
message:@"fsđs"
preferredStyle:UIAlertControllerStyleAlert
]autorelease];
UIAlertAction actionOk = [UIAlertAction actionWithTitle:@"Ok"
style:UIAlertActionStyleDefault
handler:nil];
[alert addAction:actionOk];
[self.window.rootViewController presentViewController:alert animated:YES
completion:^{
}];
I am encountering an issue with my UICollectionView layout where the background decoration view is overlapping the collection view cells. Below is the relevant code for my layout configuration:
let itemSize = NSCollectionLayoutSize(
widthDimension: .absolute(60),
heightDimension: .absolute(100)
)
let item = NSCollectionLayoutItem(layoutSize: itemSize)
let groupSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1),
heightDimension: .absolute(100)
)
let group = NSCollectionLayoutGroup.horizontal(
layoutSize: groupSize,
subitems: [item]
)
let section = NSCollectionLayoutSection(group: group)
section.decorationItems = [
NSCollectionLayoutDecorationItem.background(elementKind: "customBackgroundElementKind")
]
return section
Problem: The background decoration view is appearing on top of the collection view cells, which results in the cells being obscured.
This issue is specific to iOS 18 and does not occur on iOS 17 and below.
Request: Can anyone provide guidance or suggest a solution to ensure the decoration view does not overlap the collection view cells specifically on iOS 18?
Thank you!
Hello we have created a function that is expanding copy module to support html format. Everything inside that function works fine but on 17.4+ IOS version copying the html element strike-through tag is not working (other HTML elements are working fine) . Looking the logs seems like are getting stripped. Also list that have indents won't work on paste indent is missing. Here is the code:
void copyToClipboard(NSString *htmlContent) {
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
[pasteboard setValue:htmlContent forPasteboardType:@"public.html"];
}
Does anyone know fix for this or when this will be fixed or will it be fixed in next update?
This is a follow up to this post about building a Control Center widget to open the app directly to a particular feature. I have it working in a sample app, but when I do the same thing in my full app I get this error:
[[com.olivetree.BR-Free::com.olivetree.BR-Free.VerseWidget:com.olivetree.BR-Free.ContinueReadingPlanControl:-]] Control action: failed with error: Error Domain=ChronoKit.InteractiveWidgetActionRunner.Errors Code=1 "(null)"
Google has nothing for any of that. Can anyone shed light on what it means?
This is my control and its action:
@available(iOS 18.0, *)
struct ContinueReadingPlanControl : ControlWidget {
var body: some ControlWidgetConfiguration {
StaticControlConfiguration(kind: "com.olivetree.BR-Free.ContinueReadingPlanControl") {
ControlWidgetButton(action: ContinueReadingPlanIntent()) {
Image(systemName: "book")
}
}
.displayName("Continue Reading Plan")
}
}
@available(iOS 18.0, *)
struct ContinueReadingPlanIntent : ControlConfigurationIntent {
static let title: LocalizedStringResource = "Continue Reading Plan"
static let description = IntentDescription(stringLiteral: "Continue the last-used reading plan")
static let isDiscoverable = false
static let opensAppWhenRun: Bool = true
@MainActor
func perform() async throws -> some IntentResult & OpensIntent {
let strUrl = "olivetree://startplanday"
UserDefaults.standard.setValue(strUrl, forKey: "StartupUrl")
return .result(opensIntent: OpenURLIntent(URL(string: strUrl)!))
}
}
Note also that I'm pulling this from Console.app, streaming the logs from my device. I don't know of a way to debug a Control Center widget in Xcode, though this thread implies that it's possible.