I need a really modal alert, i.e., one which runs and allows the user interaction and closes and returns the selected option inside of a single method.
(I need to serve an API which calls my callback, presuming I show an alert, get the user's decision, and return it from that very callback. The callback comes in the main thread.)
What's the proper way to do this in i(Pad)OS 18+? Thanks!
For reference, up to 17, the following code worked nicely; in 18, it does not anymore:
volatile BOOL __block stillRuns=YES;
UIAlertController* ac=[UIAlertController alertControllerWith... preferredStyle:UIAlertControllerStyleAlert];
[ac addAction:[UIAlertAction actionWith... handler:^(UIAlertAction * _Nonnull action) {
stillRuns=NO;
}]];
...
[UIApplication.sharedApplication.keyWindow.rootViewController presentViewController:ac animated:YES completion:nil];
while (stillRuns) [NSRunLoop.currentRunLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:.1]];
UIKit
RSS for tagConstruct and manage graphical, event-driven user interfaces for iOS or tvOS apps using UIKit.
Post
Replies
Boosts
Views
Activity
private let datePicker = {
let picker = UIDatePicker()
picker.backgroundColor = .clear
picker.datePickerMode = .dateAndTime
picker.preferredDatePickerStyle = .compact
return picker
}()
I am very new to all this. What I wanted:
I wanted this textfield (where there is "I am the placeholder") to allow users to type any string:
At the moment this textfield does not let me type in anything. It sits like a stone. There are no corresponding errors to this but this behaviour is not my liking. I wanted it to let me just type string.
Could anyone kindly point me in the right direction?
This is how IBOutlet connection made to the TextField in question
And the code snippet
class ViewController: UIViewController {
@IBOutlet weak var companyTextField2: UITextField!
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
private var models = [Consulting]()
//more other codes
@IBAction func insertName(_ sender: UITextField) {
// Create the UITextField
let nameTextField = UITextField()
nameTextField.placeholder = "Enter Name"
// Option 1: Add the UITextField to the view (if needed)
view.addSubview(nameTextField)
// Option 2: Use the UITextField (e.g., get or set its text)
let enteredName = nameTextField.text
print("Entered Name:", enteredName ?? "")
}
}
1 CoreFoundation _dataWrite + 144
2 CoreFoundation _CFWriteStreamWrite + 312
3 ImageIO IIOColorMap::writeToStream(__CFWriteStream*) + 128
4 ImageIO GlobalGIFInfo::writeToStream(__CFWriteStream*, CFRange const&) + 336
5 ImageIO GlobalGIFInfo::createDataRepresentation(CFRange const&) + 80
6 ImageIO IIO_Reader_GIF::createGlobalInfoData(IIOImageReadSession*) + 68
7 ImageIO IIOReadPlugin::callDecodeImage(IIODecodeParameter*, IIOImageType, __IOSurface**, __CVBuffer**, CGImageBlockSet**) + 608
8 ImageIO IIO_Reader::CopyImageBlockSetProc(void*, CGImageProvider*, CGRect, CGSize, __CFDictionary const*) + 696
9 ImageIO IIOImageProviderInfo::copyImageBlockSetWithOptions(CGImageProvider*, CGRect, CGSize, __CFDictionary const*) + 740
10 ImageIO IIOImageProviderInfo::CopyImageBlockSetWithOptions(void*, CGImageProvider*, CGRect, CGSize, __CFDictionary const*) + 920
11 QuartzCore CA::Render::copy_image(CGImage*, CGColorSpace*, unsigned int, double, double) + 3080
12 QuartzCore CA::Render::prepare_image(CGImage*, CGColorSpace*, unsigned int, double) + 24
13 QuartzCore CA::Layer::prepare_contents(CALayer*, CA::Transaction*) + 220
14 QuartzCore CA::Layer::prepare_commit(CA::Transaction*) + 284
15 QuartzCore CA::Context::commit_transaction(CA::Transaction*, double, double*) + 484
16 QuartzCore CA::Transaction::commit() + 648
17 QuartzCore CA::Transaction::flush_as_runloop_observer(bool) + 88
18 UIKitCore __UIApplicationFlushCATransaction + 52
19 UIKitCore ___setupUpdateSequence_block_invoke_2 + 332
20 UIKitCore __UIUpdateSequenceRun + 84
21 UIKitCore _schedulerStepScheduledMainSection + 172
22 UIKitCore _runloopSourceCallback + 92
23 CoreFoundation ___CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 28
24 CoreFoundation ___CFRunLoopDoSource0 + 176
25 CoreFoundation ___CFRunLoopDoSources0 + 244
26 CoreFoundation ___CFRunLoopRun + 840
27 CoreFoundation _CFRunLoopRunSpecific + 588
28 GraphicsServices 0x00000001ebf114c0 GSEventRunModal + 164
29 UIKitCore -[UIApplication _run] + 816
30 UIKitCore _UIApplicationMain + 340
The Apple documentation for [UIViewController willMoveToParentViewController:] states,
Called just before the view controller is added or removed from a container view controller.
Hence, the view controller being popped should appear at the top of the navStack when willMoveToParentViewController: is called.
In iPadOS 16 and 17 the view controller being popped appears at the top of the navStack when willMoveToParentViewController: is called.
In iPadOS 18 the view controller being popped has already been (incorrectly) removed from the navStack. We confirmed this bug using iPadOS 18.2 as well as 18.0.
Our app relies upon the contents of the navStack within willMoveToParentViewController: to track the user's location within a folder hierarchy.
Our app works smoothly on iPadOS 16 and 17. Conversely, our customers running iPadOS 18 have lost client data and corrupted their data folders as a result of this bug! These customers are angry -- not surprisingly, some have asked for refunds and submitted negative app reviews.
Why doesn't willMoveToParentViewController: provide the correct navStack in iPadOS 18.2?
UITabBarController
|
|
VC_Tab1 --------------------------- VC_Tab2
| |
| |
VC_Tab1_Child VC_Tab2_Child
|
(HeaderView)
|
(MyButton)
The structure of the view controllers and views in the project is as described above.
<case 1>
self.navigationController?.popToRootViewController(animated: false)
tabBarController.selectedIndex = 1
When popToRootViewController(animated: false) is called in VC_Tab1_Child, followed by setting the tab controller’s selectedIndex = 1, the following results are observed:
viewWillAppear(_:), <VC_Tab2_Child>
deinit, <VC_Tab1_Child>
viewDidAppear(_:), <VC_Tab2_Child>
The originally expected results are as follows
viewWillDisappear(_:), <VC_Tab1_Child>
viewDidDisappear(_:), <VC_Tab1_Child>
deinit, <VC_Tab1_Child>
deinit, <HeaderView>
deinit, <MyButton>
headerView.backButton.rx.tap -> Event completed
headerView.backButton.rx.tap -> isDisposed
viewWillAppear(_:), <VC_Tab2_Child>
viewDidAppear(_:), <VC_Tab2_Child>
The HeaderView belonging to VC_Tab1_Child was not deallocated, and the resources associated with that view were also not released. Similarly, VC_Tab1_Child.viewWillDisappear and VC_Tab1_Child.didDisappear were not called.
<case 2>
self.navigationController?.popToRootViewController(animated: false)
DispatchQueue.main.async {
tabBarController.selectedIndex = 1
}
After performing the pop operation as shown in the code and waiting for a short period before testing, the expected results were generally achieved. (However, rarely, the results were similar to those observed when called without async.)”
<case 3>
self.navigationController?.popToRootViewController(animated: false)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
tabBarController.selectedIndex = 1
}
When a sufficient delay was ensured as described above, the expected results were achieved 100% of the time.”
The abnormal behavior is more pronounced in iOS versions prior to 18 and varies depending on the iOS version.
I couldn’t find any documentation explaining the unexpected behavior shown in the results above. What could be the cause? The simulation code is provided below.
https://github.com/linusix/UITabBarController_Test2
My code
extension MyViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(
_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath
) -> UICollectionViewCell {
if let cell = collectionView.dequeueReusableCell(
withReuseIdentifier: "CollectionViewCellID",
for: indexPath
) as? CollectionViewCell {
cell.setup()
return cell
}
return UICollectionViewCell()
}
func collectionView(
_ collectionView: UICollectionView,
didSelectItemAt indexPath: IndexPath
) {
// Unnecessary dequeue
guard collectionView.dequeueReusableCell(
withReuseIdentifier: "CollectionViewCellID",
for: indexPath
) is CollectionViewCell else { return }
// My action for selecting cell
print("Cell Selected")
}
}
Error:
*** Assertion failure in -[UICollectionView _updateVisibleCellsNow:], UICollectionView.m:5673
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Expected dequeued view to be returned to the collection view in preparation for display. When the collection view's data source is asked to provide a view for a given index path, ensure that a single view is dequeued and returned to the collection view. Avoid dequeuing views without a request from the collection view. For retrieving an existing view in the collection view, use -[UICollectionView cellForItemAtIndexPath:] or -[UICollectionView supplementaryViewForElementKind:atIndexPath:].
Solution:
The problem was doing unnecessary dequeuing in didSelectItemAt
when selecting the cell. In previous iOS like 17 or 16 or lower, it was allowed to dequeue where it is not really needed but from iOS 18, it may restricted to unnecessary dequeuing. So better to remove dequeue and use cellForItem(at) if we need to get cell from collection view.
Example
extension MyViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(
_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath
) -> UICollectionViewCell {
if let cell = collectionView.dequeueReusableCell(
withReuseIdentifier: "CollectionViewCellID",
for: indexPath
) as? CollectionViewCell {
cell.setup()
return cell
}
return UICollectionViewCell()
}
func collectionView(
_ collectionView: UICollectionView,
didSelectItemAt indexPath: IndexPath
) {
guard collectionView.cellForItem(at: indexPath) is CollectionViewCell else { return }
// My action for selecting cell
print("Cell Selected")
}
}
I can use CGContextShowText to display character.
and what I should use in CoreText?
I find there is NSAttributedString but there is lack of setShouldAntialias and setAllowsAntialiasing(Bool) in NSAttributedString
I DO NOT want to use Antialiase which means I want to set Antialiase to FALSE when I display characters
Description:
When using UIDocumentPickerViewController in iOS, if the user taps two or more files in quick succession, the picker view controller dismisses itself automatically twice. This results in an unintended behavior, leading to inconsistent screen states or redundant dismiss animations.
Steps to Reproduce:
Initialize a UIDocumentPickerViewController instance in UIDocumentPickerModeImport.
UIDocumentPickerViewController *documentPicker =
[[UIDocumentPickerViewController alloc] initWithDocumentTypes:@[(NSString *)kUTTypeData]
inMode:UIDocumentPickerModeImport];
documentPicker.delegate = self;
documentPicker.modalPresentationStyle = UIModalPresentationFullScreen;
documentPicker.allowsMultipleSelection = NO;
[self presentViewController:documentPicker animated:YES completion:nil];
Launch the document picker.
Quickly tap two or more files in succession.
Expected Behavior:
The UIDocumentPickerViewController should dismiss once and call the delegate method documentPicker:didPickDocumentsAtURLs: with the selected file(s).
Actual Behavior:
The UIDocumentPickerViewController automatically dismisses twice.
This issue occurs even when no explicit call to dismissViewControllerAnimated: is made in the delegate method.
Observed Results:
The didPickDocumentsAtURLs: callback is invoked after the picker is already dismissed.
During this process, unintended behavior such as multiple dismiss animations, view controller state corruption, or UI inconsistencies may occur.
Impact:
This issue disrupts the user experience and causes UI glitches when selecting documents.
It prevents developers from having full control over dismiss behavior or mitigating the problem programmatically.
Environment:
iOS Version: iOS 15.0 and later (also reproduced on iOS 17.4)
Device: Reproducible on multiple iPhone and iPad models
Framework: UIKit
Conclusion:
This appears to be a system-level issue with UIDocumentPickerViewController. The automatic dismiss behavior is not correctlyhandling multiple taps, causing unintended dismiss events. Developers have no explicit way to prevent this behavior or gain full control over the dismissal process.
We kindly request Apple to investigate and resolve this issue to ensure UIDocumentPickerViewController behaves as expected when interacting with multiple taps.
Hello, I am using Xcode 15.3 and doesn't add any support for Apple Intelligence yet as it requires Xcode 16+. But I see many crashlogs related to Apple Intelligence, I assume crash is related to UITextView element of UIKit.
Can you please help me to resolve this issue, how can I fix it?
There are few lines of the crashlog, they are all similar.
Thread 0 name:
Thread 0 Crashed:
0 UIKitCore 0x0000000196692d74 specialized UITextView._intelligenceCollectContent(in:collector:) + 2748 (UITextView_IntelligenceSupport.swift:37)
1 UIKitCore 0x0000000196691eb0 @objc UITextView._intelligenceCollectContent(in:collector:) + 60 (<compiler-generated>:17)
2 UIIntelligenceSupport 0x000000026b91f1e4 UIIntelligenceElementCollector.performCollection(_:) + 424 (UIIntelligenceElementCollector.swift:46)
3 UIKitCore 0x0000000196473b70 specialized UIView._intelligenceElement(in:using:transformToRoot:) + 1440 (UIView_IntelligenceSupport.swift:132)
4 UIKitCore 0x000000019647a800 specialized UIView._intelligenceCollectElement(for:in:using:transformToRoot:) + 424 (UIView_IntelligenceSupport.swift:84)
5 UIKitCore 0x00000001964792ec @objc UIView._intelligenceCollectElement(for:in:using:transformToRoot:) + 136 (<compiler-generated>:77)
6 UIKitCore 0x0000000196472c20 closure #1 in UIView._intelligenceCollectSubelements(in:using:transformToRoot:) + 256 (UIView_IntelligenceSupport.swift:55)
7 UIIntelligenceSupport 0x000000026b91f728 UIIntelligenceElementCollector.performElementCollection(_:) + 424 (UIIntelligenceElementCollector.swift:61)
v
8 UIKitCore 0x00000001964728f4 UIView._intelligenceCollectSubelements(in:using:transformToRoot:) + 928 (UIView_IntelligenceSupport.swift:54)
9 UIKitCore 0x0000000196473354 @objc UIView._intelligenceCollectSubelements(in:using:transformToRoot:) + 136 (<compiler-generated>:0)
10 UIKitCore 0x0000000196479810 closure #3 in UIView._intelligenceElement(in:using:transformToRoot:) + 256 (UIView_IntelligenceSupport.swift:165)
11 UIIntelligenceSupport 0x000000026b91fb54 UIIntelligenceElementCollector.performElementArrayCollection(_:) + 144 (UIIntelligenceElementCollector.swift:78)
...
...
225 UIIntelligenceSupport 0x000000026b8ee630 closure #1 in IntelligenceCollectionListener.collectFragments(_:) + 192 (IntelligenceCollectionListener.swift:60)
226 UIIntelligenceSupport 0x000000026b91b138 thunk for @escaping @callee_guaranteed () -> () + 36
227 CoreFoundation 0x000000019376b6e4 __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 28 (CFRunLoop.c:1818)
228 CoreFoundation 0x0000000193759910 __CFRunLoopDoBlocks + 356 (CFRunLoop.c:1860)
229 CoreFoundation 0x00000001937595f4 __CFRunLoopRun + 2432 (CFRunLoop.c:3217)
230 CoreFoundation 0x0000000193758830 CFRunLoopRunSpecific + 588 (CFRunLoop.c:3434)
231 GraphicsServices 0x00000001df7381c4 GSEventRunModal + 164 (GSEvent.c:2196)
232 UIKitCore 0x00000001962beeb0 -[UIApplication _run] + 816 (UIApplication.m:3844)
In iOS 18, using TextKit to calculate the height of attributed strings is inaccurate. The same method produces correct results in systems below iOS 18.
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(20, 40, 100, 0)];
textView.editable = NO;
textView.scrollEnabled = NO;
textView.textContainerInset = UIEdgeInsetsMake(0, 0, 0, 0);
textView.textContainer.lineFragmentPadding = 0;
textView.backgroundColor = [UIColor lightGrayColor];
[self.view addSubview:textView];
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"陈家坝好吃的撒海程邦达不差大撒把传达是吧才打卡吃吧金卡多措并举哈不好吃大杯茶十八次是吧"];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineSpacing = 4;
[attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, attributedString.length)];
[attributedString addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:16] range:NSMakeRange(0, attributedString.length)];
[attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, attributedString.length)];
textView.attributedText = attributedString;
CGFloat height = [self test:attributedString];
textView.frame = CGRectMake(20, 40, 100, height);
}
- (CGFloat)test:(NSAttributedString *)attString {
NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:attString];
NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
[textStorage addLayoutManager:layoutManager];
NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:CGSizeMake(100, CGFLOAT_MAX)];
textContainer.lineFragmentPadding = 0;
[layoutManager addTextContainer:textContainer];
[layoutManager ensureLayoutForTextContainer:textContainer];
CGFloat height = [layoutManager usedRectForTextContainer:textContainer].size.height;
return ceil(height);
}
I have a UIKit application and it contains multiple UI components like UIWindow, UIView, UIButton, etc. I wanted to perform error handling for different OS calls in my application.
For example, when creating a UIImage using init(named:) initialiser, the documentation clearly states that if the UIImage object cannot be created then the initialiser returns nil value.
However, there are other UI components like UIButton (or like UIView), which when created using init(frame:)
initialiser, the documentation does not mention for any return value.
I wanted to know how to identify If the UIButton initialisation has failed?
How is it that apple recommends should we handle these api's, If they fail to create a button. suppose If there is a case where it fails due to insufficient memory.
Or is it that apple guarantees the Api's never fail?Is there some exception that is throw? I wanted somewhat detailed answer to these questions.
In iOS 18, using TextKit to calculate the height of attributed strings is inaccurate. The same method produces correct results in systems below iOS 18.
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(20, 40, 100, 0)];
textView.editable = NO;
textView.scrollEnabled = NO;
textView.textContainerInset = UIEdgeInsetsMake(0, 0, 0, 0);
textView.textContainer.lineFragmentPadding = 0;
textView.backgroundColor = [UIColor lightGrayColor];
[self.view addSubview:textView];
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"陈家坝好吃的撒海程邦达不差大撒把传达是吧才打卡吃吧金卡多措并举哈不好吃大杯茶十八次是吧"];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineSpacing = 4;
[attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, attributedString.length)];
[attributedString addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:16] range:NSMakeRange(0, attributedString.length)];
[attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, attributedString.length)];
textView.attributedText = attributedString;
CGFloat height = [self test:attributedString];
textView.frame = CGRectMake(20, 40, 100, height);
}
- (CGFloat)test:(NSAttributedString *)attString {
// 创建 NSTextStorage 并设定文本内容
NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:attString];
// 创建 NSLayoutManager 并关联 NSTextStorage
NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
[textStorage addLayoutManager:layoutManager];
// 创建 NSTextContainer 并设定其属性
NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:CGSizeMake(100, CGFLOAT_MAX)];
textContainer.lineFragmentPadding = 0;
[layoutManager addTextContainer:textContainer];
// 强制布局管理器计算布局
[layoutManager ensureLayoutForTextContainer:textContainer];
// 获取文本内容所占的高度
CGFloat height = [layoutManager usedRectForTextContainer:textContainer].size.height;
// 返回四舍五入高度
return ceil(height);
}
我最近在18.0,18.1,18.1.1上监测到一个特殊的崩溃,无法复现,且页面日志都跟键盘有关,有没有什么思路能够处理这个问题。
0 CoreFoundation 0x00000001a224d08c __exceptionPreprocess + [ : 164] 1 libobjc.A.dylib 0x000000019f54f2e4 objc_exception_throw + [ : 88] 2 Foundation 0x00000001a161e15c _userInfoForFileAndLine 3 UIKitCore 0x00000001a56c6b2c -[UIView _multiLayerDelegatesTableCreateIfNecessary:] + [ : 208] 4 UIKitCore 0x00000001a56c6b7c -[UIView _registerMultiLayerDelegate:] + [ : 36] 5 UIKitCore 0x00000001a4ceadb8 -[_UIPortalView setSourceView:] + [ : 132] 6 UIKitCore 0x00000001a5a35888 -[_UIPortalView initWithSourceView:] + [ : 68] 7 UIKitCore 0x00000001a5a5e038 -[_UITextMagnifiedLoupeView initWithSourceView:] + [ : 444] 8 UIKitCore 0x00000001a5f0f894 +[UITextLoupeSession _makeLoupeViewForSourceView:selectionWidget:orientation:] + [ : 84] 9 UIKitCore 0x00000001a5f0fa34 +[UITextLoupeSession _beginLoupeSessionAtPoint:fromSelectionWidgetView:inView:orientation:] + [ : 304] 10 UIKitCore 0x00000001a55a0b9c -[UITextRefinementTouchBehavior textLoupeInteraction:gestureChangedWithState:location:translation:velocity:modifierFlags:shouldCancel:] + [ : 1756] 11 UIKit 0x000000025aff6310 -[UITextRefinementTouchBehaviorAccessibility textLoupeInteraction:gestureChangedWithState:location:translation:velocity:modifierFlags:shouldCancel:] + [ : 216]
In previous versions, set strokeWidth and strokeColor , and no raised lines inside the border
but , the same code run with code 16.0+ at iOS 18.0+ iPhone , it has raised lines inside the border
how to fix it .
In previous versions, strokeWidth and strokeColor were set, and now there will be raised lines inside the border
how to fix it
Hi! I was trying to add an animation to my SwiftUI view with UIKit, but after the animation runs there's a delay before the view will accept touch interactions. I thought it was because of the frame size of the view controller, but even after fixing that I still get the delay. Could anyone point me to where I might be going wrong, or if maybe using a UIKit modifier for the animation just doesn't work?
Any help would be greatly appreciated!
UIView:
class BounceView: UIView {
required init() {
super.init(frame: .zero)
}
func bounceAnimation() {
guard let piece = self.subviews.first else { return }
UIView.animate(withDuration: 0.7, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0) {
piece.frame.origin.x += 10
}
}
func bounceBack() {
guard let piece = self.subviews.first else { return }
UIView.animate(withDuration: 0.7, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0) {
piece.frame.origin.x -= 10
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
UIView controller:
class BounceViewController: UIViewController {
init(controller: UIViewController) {
super.init(nibName: nil, bundle: nil)
view = BounceView()
addChild(controller)
controller.view.translatesAutoresizingMaskIntoConstraints = false
controller.view.backgroundColor = .clear
view.addSubview(controller.view)
controller.didMove(toParent: self)
}
// adjusts view to match bounds of child
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let subviewFrame = self.view.subviews.first?.bounds ?? .zero
view.frame = subviewFrame
print(subviewFrame)
self.updateViewConstraints()
}
func update(animated: Bool) {
let bounceView = view as? BounceView
if animated {
bounceView?.bounceAnimation()
} else {
bounceView?.bounceBack()
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
SwiftUI wrapper:
struct BounceUIViewController: UIViewControllerRepresentable {
private var controller: UIViewController
@Binding var animated: Bool
init(controller: UIViewController, animated: Binding<Bool>) {
self.controller = controller
self._animated = animated
}
func makeUIViewController(context: Context) -> BounceViewController {
BounceViewController(controller: controller)
}
func updateUIViewController(_ uiViewController: BounceViewController, context: Context) {
uiViewController.update(animated: animated)
}
}
View extension:
extension View {
func bounce(animated: Binding<Bool>) -> some View {
modifier(Bounce(animated: animated))
}
}
struct Bounce: ViewModifier {
@Binding var animated: Bool
init(animated: Binding<Bool>) {
self._animated = animated
}
func body(content: Content) -> some View {
BounceUIViewController(controller: content.uiViewController, animated: $animated)
}
}
Is there any way to change lens correction on iPad programatically using AVCapture?
I was looking out for the error handling for rendering the Widgets(like UIButton, UIVIew etc) on the screen in iOS. I am painting the screen programmatically using swift.
Considering a simple Widget(like for say UIButton) when we try to create using its initializer and set some properties like 'setTitle' . These functions neither return any value upon success/failure nor in documentation they have mentioned about any exceptions which would be raised upon failure.
https://developer.apple.com/documentation/uikit/uibutton/settitle(_:for:)
So, how to do error handling here in this scenarios, in case the apis fail to due some reason, like memory issue? There must be some scenarios for these api failure.
I'm trying to implement a Help Window from Help Menu in macOS (Mac Catalyst). I have SceneConfiguration in Info.plist and multi-window enabled. Tapping Help menu opens a new Help Window on macOS. I thought it was working great!
Unfortunately, tapping Help menu again opens a new Help Window. I only want one Help window to be shown.
I expected UIApplication.shared.activateSceneSession(for: request) to use an existing UIScene if one was already present. In my experience I always get a new Scene and thus a new Window. What am I missing?
AppDelegate.swift
func application(_ application: UIApplication,
configurationForConnecting connectingSceneSession: UISceneSession,
options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// It's important that each UISceneConfiguration have a unique configuration name.
var configurationName: String!
switch options.userActivities.first?.activityType {
case UserActivity.HelpMenuActivityType:
configurationName = SceneConfiguration.helpWindowConfiguration
default:
configurationName = SceneConfiguration.defaultConfiguration
}
return UISceneConfiguration(name: configurationName, sessionRole: connectingSceneSession.role)
}
override func buildMenu(with builder: UIMenuBuilder) {
super.buildMenu(with: builder)
...
builder.remove(menu: .help)
builder.insertSibling(helpMenu(), afterMenu: .window)
}
func helpMenu() -> UIMenu {
let children: [UIAction] = [
UIAction(...
) { [weak self] action in
self?.helpMenuTappedHandler(action)
}
]
....
}
func helpMenuTappedHandler(_ action: UIAction) {
let userActivity: NSUserActivity = ...
userActivity.targetContentIdentifier = ...
let options: UIScene.ActivationRequestOptions = .init()
options.requestingScene = ...
let request: UISceneSessionActivationRequest = .init(role: .windowApplication, userActivity: userActivity, options: options)
UIApplication.shared.activateSceneSession(for: request, errorHandler: handleHelpError)
}