Construct and manage graphical, event-driven user interfaces for iOS or tvOS apps using UIKit.

UIKit Documentation

Posts under UIKit tag

1,022 Posts
Sort by:
Post marked as solved
1 Replies
128 Views
I understand that shouldAutorotate has been deprecated in IOS16 and forcing orientations using UIDevice have also gone away. But it's not clear to me how we can prevent orientation changes using the new api. I have managed to force orientation changes using requestGeometryUpdate but nothing I do seems to stop it from rotating back again after the forced rotation. I've tried calling setNeedsUpdateOfSupportedInterfaceOrientations on both the current view controller and the navigation controller but supportedInterfaceOrientations never seems to be called. supportedInterfaceOrientations is called on the first load, but it seems to be ignored as regardless of what I put in there the device will rotate to all the options allowed in the info.plist. What trick am I missing?
Posted
by
Post not yet marked as solved
0 Replies
56 Views
I am trying to set and maintain the zoomScale value on the scrollView associated with a WKWebView. I can set the value without issue. I have noticed, however, that when the size of the webpage changes (due to a change in content), the zoomScale gets reset back to 1. Also, this reset behavior does not occur if the zoomScale is set via a pinch gesture by the user. Is there something I can do to maintain the programmatically set zoomScale when the size of the web page changes?
Posted
by
Post not yet marked as solved
0 Replies
104 Views
When I hover the mouse over the NSTextAttachment image inside the UITextview, it should show this option to MarkUp. All native app including Notes, TextEditor, Mail have this behaviour: I think, by default, NSTextView will show the NSSharingServicePicker button when you hover over an image inside the text view. That’s true even for custom image-based NSTextAttachments in the attributed string. But it is not showing the button for UITextview in MacCatalyst. Also NSSharingService class is limited to MacOS only. Are there any alternative way to achieve this in MacCatalyst?
Posted
by
Post not yet marked as solved
1 Replies
147 Views
UITextview's Spellchecker seem not to detect spells and show red dots at odd position in MacCatalyst: It does work well in iPhone and iPad though. I've activated the Spellcheck through storyboard, also tested with both Normal and Attributed strings. Even tried disabling the scrolling. But nothing seems to help! Does any one know about this behaviour?
Posted
by
Post not yet marked as solved
0 Replies
91 Views
Im observing a bigger down size of my text when using .adjustsFontSizeToFitWidth on iOS15 vz iOS14 Xcode 13 but i haven't find any release notes explaining why. My observations are this: Same frame for the label result on a different text size in a proportion of heiht: 1, width:4 even more stranger if I increase the height of the frame the behavior returns to be like the old one and this don't affect behavior on iOS14 // First label is render smaller on iOS 15 vz 14 UILabel *yourLabel1 = [[UILabel alloc] initWithFrame:CGRectMake(0, 100, 160, 40)]; [yourLabel1 setTextColor:[UIColor brownColor]]; [yourLabel1 setBackgroundColor:[UIColor systemRedColor]]; [yourLabel1 setFont:[UIFont boldSystemFontOfSize:52]]; [yourLabel1 setText:@"HELLO"]; yourLabel1.minimumScaleFactor = 0.2; yourLabel1.adjustsFontSizeToFitWidth = YES; [self.view addSubview:yourLabel1]; // Second label is render equal on iOS 15 and 14 only difference is a change on the height UILabel *yourLabel2 = [[UILabel alloc] initWithFrame:CGRectMake(0, 300, 160, 60)]; [yourLabel2 setTextColor:[UIColor brownColor]]; [yourLabel2 setBackgroundColor:[UIColor systemRedColor]]; [yourLabel2 setFont:[UIFont boldSystemFontOfSize:52]]; [yourLabel2 setText:@"HELLO"]; yourLabel2.minimumScaleFactor = 0.2; yourLabel2.adjustsFontSizeToFitWidth = YES; [self.view addSubview:yourLabel2];
Posted
by
Post not yet marked as solved
0 Replies
74 Views
It looks like a custom keyboard created through an UIInputViewController doesn't have access to all events. How can one know inside a messaging App that the Send button was tapped? And how does one know what text was sent and text was not sent when the keyboard is closed? Is this a privacy policy or is there an API I am missing?
Posted
by
Post not yet marked as solved
0 Replies
61 Views
Hi, is it possible to customize the colors of the icons and placeholders in the SearchField created with the .searchable modifier in SwiftUI? I am currently using a dark navigation bar in the .light color scheme (and the other way around). This makes the SearchField unreadable since the contrast is very low.
Posted
by
Post marked as solved
8 Replies
142 Views
In my app, users can select from a range of UI color-palettes to customize the look of the app to suite their preference. The app's root viewcontroller is a UINavigationController (this app is not using SwiftUI, nor has it adopted UIScene yet). However, I noticed only the first time (to be specific: this is in the appDelegate's application(:didFinishLaunchingWithOptions:), so before anything is actually rendered to the screen) the appearance settings are applied, but subsequent changes do not take effect. However, the following code seems to 'fix' the issue: self.window?.rootViewController = nil self.updateAppearance() self.window?.rootViewController = navigationController This to me seems hacky/kludgy and unlikely to be a sustainable 'fix', and I think it indicates that the appearance information is only taken into account when a view(controller) gets inserted into the view(controller) hierarchy, in other words: when it gets drawn. So then the question would be: how to tell a UINavigationController / Bar to redraw using the updated appearance settings? I'm sure I'm overlooking something relatively simple (as I imagine this kind of thing is something many apps do to support darkmode), but alas, I can't seem to find it. I setup a small test-project to isolate this issue. It has only one custom viewcontroller (ContentViewController) which only sets the backgroundColor in viewDidLoad(), and an AppDelegate (code below). No storyboards, no UIScene related things. So, here is the minimal code that reproduces my issue: AppDelegate.swift: import UIKit @main class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? var rootNavigationController: UINavigationController? let contentViewController = ViewController() let timer = DispatchSource.makeTimerSource(queue: DispatchQueue.main) func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { window = UIWindow() let navigationController = UINavigationController(rootViewController: contentViewController) rootNavigationController = navigationController window?.rootViewController = navigationController window?.makeKeyAndVisible() // initial setup of appearance, this first call will take effect as expected updateAppearance() // setup a timer to repeatedly change the appearance of the navigationbar timer.setEventHandler { /// ! uncommenting this line and the one after `self.updateAppearance()` /// will cause `self.updateAppearance()` to take effect as expected // self.window?.rootViewController = nil self.updateAppearance() //self.window?.rootViewController = navigationController } timer.schedule(deadline: .now(), repeating: .seconds(2), leeway: .milliseconds(50)) timer.resume() return true } // some vars to automatically toggle between colors / textstyles var colorIndex = 0 let colors = [ UIColor.blue, UIColor.yellow] let textStyles: [UIFont.TextStyle] = [.title3, .body] func updateAppearance() { let color = colors[colorIndex] let textStyle = textStyles[colorIndex] contentViewController.title = "bgColor: \(colorIndex) \(textStyle.rawValue)" colorIndex = (colorIndex == 0) ? 1 : 0 let textColor = colors[colorIndex] self.rootNavigationController?.navigationBar.isTranslucent = false let navigationBarAppearance = UINavigationBarAppearance() navigationBarAppearance.configureWithOpaqueBackground() navigationBarAppearance.backgroundColor = color         let textAttributes: [NSAttributedString.Key : Any] =         [.font: UIFont.preferredFont(forTextStyle: textStyle),          .foregroundColor: textColor ] navigationBarAppearance.titleTextAttributes = textAttributes UINavigationBar.appearance().standardAppearance = navigationBarAppearance UINavigationBar.appearance().compactAppearance = navigationBarAppearance UINavigationBar.appearance().scrollEdgeAppearance = navigationBarAppearance } } ViewController: import UIKit class ViewController: UIViewController {     override func viewDidLoad()     {         super.viewDidLoad()         view.backgroundColor = UIColor.lightGray     } }
Posted
by
Post not yet marked as solved
0 Replies
98 Views
I have made an UICollectionView in which you can double tap a cell to resize it. I'm using a CompositionalLayout, a DiffableDataSource and the new UIHostingConfiguration hosting a SwiftUI View which depends on an ObservableObject. The resizing is triggered by updating the height property of the ObservableObject. That causes the SwiftUI View to change its frame which leads to the collectionView automatically resizing the cell. The caveat is that it does so immediately without animation only jumping between the old and the new frame of the view. The ideal end-goal would be to be able to add a .animation() modifier to the SwiftUI View that then determines animation for both view and cell. Doing so now without additional setup makes the SwiftUI View animate but not the cell. Is there a way to make the cell (orange) follow the size of the view (green) dynamically? The proper way to manipulate the cell animation (as far as I known) is to override initialLayoutAttributesForAppearingItem() and finalLayoutAttributesForDisappearingItem() but since the cell just changes and doesn't appear/disappear they don't have an effect. One could also think of Auto Layout constraints to archive this but I don’t think they are usable with UIHostingConfiguration? I've also tried: subclassing UICollectionViewCell and overriding apply(_ layoutAttributes: UICollectionViewLayoutAttributes) but it only effects the orange cell-background on initial appearance. to put layout.invalidateLayout() or collectionView.layoutIfNeeded() inside UIView.animate() but it does not seem to have an effect on the size change. Any thoughts, hints, ideas are greatly appreciated ✌️ Cheers! Here is the code I used for the first gif: struct CellContentModel { var height: CGFloat? = 100 } class CellContentController: ObservableObject, Identifiable { let id = UUID() @Published var cellContentModel: CellContentModel init(cellContentModel: CellContentModel) { self.cellContentModel = cellContentModel } } class DataStore { var data: [CellContentController] var dataById: [CellContentController.ID: CellContentController] init(data: [CellContentController]) { self.data = data self.dataById = Dictionary(uniqueKeysWithValues: data.map { ($0.id, $0) } ) } static let testData = [ CellContentController(cellContentModel: CellContentModel()), CellContentController(cellContentModel: CellContentModel(height: 80)), CellContentController(cellContentModel: CellContentModel()) ] } class CollectionViewController: UIViewController { enum Section { case first } var dataStore = DataStore(data: DataStore.testData) private var layout: UICollectionViewCompositionalLayout! private var collectionView: UICollectionView! private var dataSource: UICollectionViewDiffableDataSource<Section, CellContentController.ID>! override func loadView() { createLayout() createCollectionView() createDataSource() view = collectionView } } // - MARK: Layout extension CollectionViewController { func createLayout() { let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(50)) let Item = NSCollectionLayoutItem(layoutSize: itemSize) let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.8), heightDimension: .estimated(300)) let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [Item]) let section = NSCollectionLayoutSection(group: group) layout = .init(section: section) } } // - MARK: CollectionView extension CollectionViewController { func createCollectionView() { collectionView = .init(frame: .zero, collectionViewLayout: layout) let doubleTapGestureRecognizer = DoubleTapGestureRecognizer() doubleTapGestureRecognizer.doubleTapAction = { [unowned self] touch, _ in let touchLocation = touch.location(in: collectionView) guard let touchedIndexPath = collectionView.indexPathForItem(at: touchLocation) else { return } let touchedItemIdentifier = dataSource.itemIdentifier(for: touchedIndexPath)! dataStore.dataById[touchedItemIdentifier]!.cellContentModel.height = dataStore.dataById[touchedItemIdentifier]!.cellContentModel.height == 100 ? nil : 100 } collectionView.addGestureRecognizer(doubleTapGestureRecognizer) } } // - MARK: DataSource extension CollectionViewController { func createDataSource() { let cellRegistration = UICollectionView.CellRegistration<UICollectionViewCell, CellContentController.ID>() { cell, indexPath, itemIdentifier in let cellContentController = self.dataStore.dataById[itemIdentifier]! cell.contentConfiguration = UIHostingConfiguration { TextView(cellContentController: cellContentController) } .background(.orange) } dataSource = .init(collectionView: collectionView) { collectionView, indexPath, itemIdentifier in return collectionView.dequeueConfiguredReusableCell(using: cellRegistration, for: indexPath, item: itemIdentifier) } var initialSnapshot = NSDiffableDataSourceSnapshot<Section, CellContentController.ID>() initialSnapshot.appendSections([Section.first]) initialSnapshot.appendItems(dataStore.data.map{ $0.id }, toSection: Section.first) dataSource.applySnapshotUsingReloadData(initialSnapshot) } } class DoubleTapGestureRecognizer: UITapGestureRecognizer { var doubleTapAction: ((UITouch, UIEvent) -> Void)? override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) { if touches.first!.tapCount == 2 { doubleTapAction?(touches.first!, event) } } } struct TextView: View { @StateObject var cellContentController: CellContentController var body: some View { Text(cellContentController.cellContentModel.height?.description ?? "nil") .frame(height: cellContentController.cellContentModel.height, alignment: .top) .background(.green) } }
Posted
by
Post not yet marked as solved
0 Replies
47 Views
I have this code to adjust UITextView when keyboard is about to be displayed. @objc func keyboardWillShow(notification: NSNotification) { if let rectValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue { let keyboardSize = rectValue.cgRectValue.size let contentInsets: UIEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height - view.safeAreaInsets.bottom, right: 0) textView.contentInset = contentInsets textView.scrollIndicatorInsets = contentInsets } } I see setting contentInset automatically creates a scrolling animation (after the keyboard appears fully) that makes the text at the cursor visible. The animation happens automatically and there is no way to disable it. I want to scroll to a given location in the textView sometimes when the keyboard is presented (preferably, animating it along with keyboard appearance). The implicit contentInset animation makes it impossible however. First the keyboard animates, then contentInset animates, and now only can I animate to my chosen location in textView. This is awkward. I am wondering what is the right way to achieve it?
Posted
by
Post not yet marked as solved
0 Replies
144 Views
I made an UICollectionView that uses a CompositionalLayout, DiffableDataSource, the new UIHostingConfiguration and an ObservableObject. You can resize cells by double tapping them (see gif + example code). The resizing is triggered by updating the ObservableObject. Now I want to set an animation mainly to animate the shrinking as well as the size change of the last cell but I can't seem to find the right way to do so. By default there is no animation when shrinking and on the last cell: While there are many guides on how to create dynamically resizeable cells they all either use changes in Autolayout constraints (which can't be used with UIHostingConfiguration - correct me if I'm wrong) or they add an optional part to the view inside UIHostingConfiguration with "if some condition {MyAdditionalView(); .transition(someTransition)}" instead of changing its frame. I also tried these different ways to manipulate the animation but with no success: setting an animation modifier .animation(): this makes a fading animation appear and the view inside the hosting configuration starts to jump (It seems to be anchored in the centre of the cell). setting a transition modifier .transition(): this has no effect on the animation. subclassing UICompositionalLayout and overriding initialLayoutAttributesForAppearingItem(at itemIndexPath: IndexPath) as well as finalLayoutAttributesForDisappearingItem(at itemIndexPath: IndexPath): this has no effect on the animation. subclassing UICollectionViewCell and overriding apply(_ layoutAttributes: UICollectionViewLayoutAttributes): this only effects the orange cell-background on initial appearance. using snapshot.reloadItems([ItemIdentifier]) or snapshot.reconfigureItems([ItemIdentifier]): they have no effect on the animation and lead to inconsistent behaviour when combined with ObservableObject. setting collectionView.selfSizingInvalidation = .enabledIncludingConstraints: no effect. Setting it to .disabled stops the orange cells from resizing altogether. Is there a way to customize the size change animation of a cell using UIHostingConfiguration and ObservableObject? Code without animation: struct CellContentModel {     var height: CGFloat? = 100 } class CellContentController: ObservableObject, Identifiable {     let id = UUID()     @Published var cellContentModel: CellContentModel     init(cellContentModel: CellContentModel) {         self.cellContentModel = cellContentModel     } } class DataStore {     var data: [CellContentController]     var dataById: [CellContentController.ID: CellContentController]     init(data: [CellContentController]) {         self.data = data         self.dataById = Dictionary(uniqueKeysWithValues: data.map { ($0.id, $0) } )     }     static let testData = [         CellContentController(cellContentModel: CellContentModel()),         CellContentController(cellContentModel: CellContentModel(height: 80)),         CellContentController(cellContentModel: CellContentModel())     ] } class CollectionViewController: UIViewController {     enum Section {         case first     }     var dataStore = DataStore(data: DataStore.testData)     private var layout: UICollectionViewCompositionalLayout!     private var collectionView: UICollectionView!     private var dataSource: UICollectionViewDiffableDataSource<Section, CellContentController.ID>!     override func loadView() {         createLayout()         createCollectionView()         createDataSource()         view = collectionView     } } // - MARK: Layout extension CollectionViewController {     func createLayout() {         let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(50))         let Item = NSCollectionLayoutItem(layoutSize: itemSize)         let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.8), heightDimension: .estimated(300))         let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [Item])         let section = NSCollectionLayoutSection(group: group)         layout = .init(section: section)     } } // - MARK: CollectionView extension CollectionViewController {     func createCollectionView() {         collectionView = .init(frame: .zero, collectionViewLayout: layout)         let doubleTapGestureRecognizer = DoubleTapGestureRecognizer()         doubleTapGestureRecognizer.doubleTapAction = { [unowned self] touch, _ in             let touchLocation = touch.location(in: collectionView)             guard let touchedIndexPath = collectionView.indexPathForItem(at: touchLocation) else { return }             let touchedItemIdentifier = dataSource.itemIdentifier(for: touchedIndexPath)!             dataStore.dataById[touchedItemIdentifier]!.cellContentModel.height = dataStore.dataById[touchedItemIdentifier]!.cellContentModel.height == 100 ? nil : 100 // <- this triggers the resizing }         collectionView.addGestureRecognizer(doubleTapGestureRecognizer)     } } // - MARK: DataSource extension CollectionViewController {     func createDataSource() {         let cellRegistration = UICollectionView.CellRegistration<C, CellContentController.ID>() { cell, indexPath, itemIdentifier in             let cellContentController = self.dataStore.dataById[itemIdentifier]!             cell.contentConfiguration = UIHostingConfiguration {                 TextView(cellContentController: cellContentController)             }             .background(.orange)         }         dataSource = .init(collectionView: collectionView) { collectionView, indexPath, itemIdentifier in             return collectionView.dequeueConfiguredReusableCell(using: cellRegistration, for: indexPath, item: itemIdentifier)         }         var initialSnapshot = NSDiffableDataSourceSnapshot<Section, CellContentController.ID>()         initialSnapshot.appendSections([Section.first])         initialSnapshot.appendItems(dataStore.data.map{ $0.id }, toSection: Section.first)         dataSource.applySnapshotUsingReloadData(initialSnapshot)     } } class DoubleTapGestureRecognizer: UITapGestureRecognizer {     var doubleTapAction: ((UITouch, UIEvent) -> Void)?     override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {         if touches.first!.tapCount == 2 {             doubleTapAction?(touches.first!, event)         }     } } struct TextView: View {     @StateObject var cellContentController: CellContentController     var body: some View { Text(cellContentController.cellContentModel.height?.description ?? "nil")             .frame(height: cellContentController.cellContentModel.height)             .background(.green)     } }
Posted
by
Post not yet marked as solved
6 Replies
153 Views
Please help me understand what will be better for the complex app for the Apple platform I read a few articles about UIKit vs SwiftUI and quoted one of the articles <You can choose UIKit if you want maximum control over how your app looks. > this phrase is a little confused me. I know about widgets, rendering ideas, minimum iOS version, live preview, and speed of development, I am not worried about this stuff. This question is easy to get an answer to but with the complex app it's a big problem, I will try to focus on key points for a more accurate representation of the problem. My requirements for the app are: Future supporting, ideally one app for iOS and Mac OS platform( exclude audience that prefers Mac platform for work, UI should be different). Maximum UI control, I mean animation and interaction, the application will be huge. Classic UI like in Apple News, Podcasts, App Store. Complex architecture like VIP. I don’t have enough experience with SwiftUI, but can say that can do all that I want using UIKit, my one complex example with SwiftUI and UIKit was 3D Carousel, and I can say that this is easy using SwiftUI, but it was only one complex stuff which I tried and that’s it In short form, my question is: can I do any interaction and most of the animation using SwiftUI, because I hope in another interaction like DB, etc it will not be a problem.
Posted
by
Post not yet marked as solved
0 Replies
67 Views
This issue is driving me crazy. I load an NSAttributedString in UITextView and within moments after loading the foregroundColor attribute of text is erased(i.e becomes white) without me doing anything. Here is the code and NSLog dump. How do I debug this I wonder? class ScriptEditingView: UITextView, UITextViewDelegate { var defaultFont = UIFont.preferredFont(forTextStyle: .body) var defaultTextColor = UIColor.white private func commonInit() { self.font = UIFont.preferredFont(forTextStyle: .body) self.allowsEditingTextAttributes = true self.textColor = defaultTextColor self.backgroundColor = UIColor.black self.isOpaque = true self.isEditable = true self.isSelectable = true self.dataDetectorTypes = [] self.showsHorizontalScrollIndicator = false } } And then in my ViewController that contains the UITextView, I have this code: textView = ScriptEditingView(frame: newTextViewRect, textContainer: nil) textView.delegate = self view.addSubview(textView) textView.allowsEditingTextAttributes = true let guide = view.safeAreaLayoutGuide // 5 textView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ textView.leadingAnchor.constraint(equalTo: guide.leadingAnchor), textView.trailingAnchor.constraint(equalTo: guide.trailingAnchor), textView.topAnchor.constraint(equalTo: view.topAnchor), textView.bottomAnchor.constraint(equalTo: view.bottomAnchor) ]) textView.attributedText = attributedString NSLog("Attributed now") dumpAttributesOfText() DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { NSLog("Attributes after 1 sec") self.dumpAttributesOfText() } And here is code to dump attributes of text: private func dumpAttributesOfText() { textView.attributedText?.enumerateAttributes(in: NSRange(location: 0, length: textView.attributedText!.length), options: .longestEffectiveRangeNotRequired, using: { dictionary, range, stop in NSLog(" range \(range)") if let font = dictionary[.font] as? UIFont { NSLog("Font at range \(range) - \(font.fontName), \(font.pointSize)") } if let foregroundColor = dictionary[.foregroundColor] as? UIColor { NSLog("Foregroundcolor \(foregroundColor) at range \(range)") } if let underline = dictionary[.underlineStyle] as? Int { NSLog("Underline \(underline) at range \(range)") } }) } The logs show this: 2022-07-02 13:16:02.841199+0400 MyApp[12054:922491] Attributed now 2022-07-02 13:16:02.841370+0400 MyApp[12054:922491] range {0, 14} 2022-07-02 13:16:02.841486+0400 MyApp[12054:922491] Font at range {0, 14} - HelveticaNeue, 30.0 2022-07-02 13:16:02.841586+0400 MyApp[12054:922491] Foregroundcolor UIExtendedGrayColorSpace 1 1 at range {0, 14} 2022-07-02 13:16:02.841681+0400 MyApp[12054:922491] range {14, 6} 2022-07-02 13:16:02.841770+0400 MyApp[12054:922491] Font at range {14, 6} - HelveticaNeue, 30.0 2022-07-02 13:16:02.841855+0400 MyApp[12054:922491] Foregroundcolor kCGColorSpaceModelRGB 0.96863 0.80784 0.27451 1 at range {14, 6} 2022-07-02 13:16:03.934816+0400 MyApp[12054:922491] Attributes after 1 sec 2022-07-02 13:16:03.935087+0400 MyApp[12054:922491] range {0, 20} 2022-07-02 13:16:03.935183+0400 MyApp[12054:922491] Font at range {0, 20} - HelveticaNeue, 30.0 2022-07-02 13:16:03.935255+0400 MyApp[12054:922491] Foregroundcolor UIExtendedGrayColorSpace 1 1 at range {0, 20}
Posted
by
Post not yet marked as solved
1 Replies
106 Views
In this documentation for completeRequest(returningItems:completionHandler:), there is a box shaded yellow that says: Important If the system calls your block with an expired value of true, you must immediately suspend your app extension. If you fail to do this, the system terminates your extension’s process. How does my app or my Share Extension know when the system calls the block spoken of?
Posted
by
Post not yet marked as solved
0 Replies
97 Views
Does anyone experience this before? I am using an AVPlayer to present a video. The app has only one .mp4 but for a different use case, the same video needs to get flipped. Both videos (the normal and the flipped one) work fine on iOS 15.5 but the flipped video does not show the play and the 15 seconds forward/backward buttons in iOS 16 (see image attached). The buttons are there and completely functional, you can press the play and the 15 seconds forward/backward buttons but they don't appear in the screen (4th video in the attached image) The code the app is using to flip the video is as follows: (The code that flips the video is in the if block). presenter.present(avPlayerController, animated: true, completion: { let url = URL(fileURLWithPath: path) let avPlayer = self.dependency.avPlayerFactory(url) if doFlip() { let flippedLayer = AVPlayerLayer(player: avPlayer as? AVPlayer) let transform = CGAffineTransform(scaleX: -1.0, y: 1.0) flippedLayer.frame = (avPlayerController as UIViewController).view.frame flippedLayer.setAffineTransform(transform) (avPlayerController as UIViewController).view.layer.addSublayer(flippedLayer) } avPlayerController.player = avPlayer as? AVPlayer avPlayer.play() })
Posted
by
Post not yet marked as solved
0 Replies
102 Views
XCODE 14 / iOS 16 beta 2 on both simulator and iPad 6, the below warning is issued for all views in my app with a Navigation bar with buttons. Navigation bar colours are customised and buttons added programatically. Is anyone else seeing this? Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want.  Try this:  (1) look at each constraint and try to figure out which you don't expect;  (2) find the code that added the unwanted constraint or constraints and fix it.  (     "<NSLayoutConstraint:0x13bb1e2b0 UIImageView:0x135dfcae0.width <= _UIModernBarButton:0x13be321e0.width   (active)>",     "<NSLayoutConstraint:0x13bbf14b0 '_UITemporaryLayoutWidth' _UIButtonBarButton:0x13be31d10.width == 0   (active)>",     "<NSLayoutConstraint:0x13bb844a0 'IB_Leading_Leading' H:|-(>=11)-[_UIModernBarButton:0x13be321e0]   (active, names: '|':_UIButtonBarButton:0x13be31d10 )>",     "<NSLayoutConstraint:0x13bbad9a0 'IB_Trailing_Trailing' H:[_UIModernBarButton:0x13be321e0]-(>=11)-|   (active, names: '|':_UIButtonBarButton:0x13be31d10 )>" ) Will attempt to recover by breaking constraint  <NSLayoutConstraint:0x13bb1e2b0 UIImageView:0x135dfcae0.width <= _UIModernBarButton:0x13be321e0.width   (active)>
Posted
by
Post not yet marked as solved
1 Replies
75 Views
My viewWillAppear (below) worked before iOS 15.5. Now, as part of super.viewWillAppear the OS calls titleForHeaderInSection, which crashes. It crashes because it calls getHeaderText, which depends on my variable monitor being bound. monitor doesn't get bound until my function setupUserGuideMonitor() is called. class myClass: UITableViewController { var monitor: UserGuideMonitor! override func viewWillAppear(_ animated: Bool) {         super.viewWillAppear(animated)         self.setupUserGuideMonitor()         self.listenForNotifications()     } } There are various ways to fix this, including calling setupUserGuidMonitor before super.viewWillAppear, but my understanding of best practices is that only minimum setup should occur before super gets called. I have a very large code base with lots of other complex viewWillAppear calls and I am worried about other fallout from this change and other similar changes that may have occurred. I found nothing about this in the release notes for 15.5. In general I'd like to know what protocol methods are going to be invoked during a viewWillAppear. It's not like I can look at the source code for UITableViewController.
Posted
by
Post not yet marked as solved
0 Replies
62 Views
I am trying to create a custom transition, similar to the one that is on the App Store. I used these tutorials: https://eric-dockery283.medium.com/custom-view-transitions-like-the-new-app-store-a2a1181229b6 https://www.raywenderlich.com/2925473-ios-animation-tutorial-custom-view-controller-presentation-transitions I have also been experimenting with using the load view to have the root view to create the view. now what I am doing is that I am using a collectionview, which I want to keep, and when an item is pressed it animate transitions to a new view controller with a larger image, simple. the problem is that when I combine it with using the loadView with view = rootView() it did not work in some scenarios. For example: when I use the modalPresentationStyle = .fullScreen, when I press an item in the collection view the screen just goes black, and then when I press the view hierarchy it shows this: when I remove the modalPresentationStyle = .fullScreen it does animate but it is the popover transition, which I do not want. What I want is to have a full screen transition that is animated. here is the view controller: import UIKit class OtherViewController: UIViewController, UIViewControllerTransitioningDelegate {   var data: DogArr?   var rootView = testView1()   override func viewDidLoad() {     super.viewDidLoad()     self.view.backgroundColor = .systemBackground   }   override func loadView() {     view = rootView     rootView.animalImg.image = UIImage(named: data?.image ?? "")     rootView.dismissBtn.addTarget(self, action: #selector(dismissingBtn), for: .touchUpInside)   }   @objc func dismissingBtn() {     self.dismiss(animated: true)   } } class testView1: UIView {   var animalImg: UIImageView = {     let img = UIImageView()     img.contentMode = .scaleAspectFit     img.translatesAutoresizingMaskIntoConstraints = false     return img   }()   var dismissBtn: UIButton = {     let btn = UIButton()     btn.translatesAutoresizingMaskIntoConstraints = false     btn.setTitle("Done", for: .normal)     btn.titleLabel?.font = UIFont.systemFont(ofSize: 25)     btn.titleLabel?.textAlignment = .center     btn.setTitleColor(.label, for: .normal)     btn.contentMode = .scaleAspectFill     return btn   }()   init() {     super.init(frame: .zero)     self.addSubview(animalImg)     self.addSubview(dismissBtn)     animalImg.translatesAutoresizingMaskIntoConstraints = false     self.backgroundColor = .systemBackground     NSLayoutConstraint.activate([       animalImg.topAnchor.constraint(equalTo: self.topAnchor),       animalImg.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 0.5),       animalImg.widthAnchor.constraint(equalTo: animalImg.heightAnchor),       dismissBtn.topAnchor.constraint(equalTo: self.animalImg.bottomAnchor, constant: 20),       dismissBtn.centerXAnchor.constraint(equalTo: self.dismissBtn.centerXAnchor),       dismissBtn.widthAnchor.constraint(equalToConstant: 150),       dismissBtn.heightAnchor.constraint(equalToConstant: 75)     ])   }   required init?(coder: NSCoder) {     fatalError("init(coder:) has not been implemented")   } } I noticed that when I remove the root view and just created everything in the view controller, it seems to work, the thing is that this is just a test for now. The root view in a future project may be very large so I think keeping to a rootview may be a good idea. If there are any other methods similar, please share. If there is anything I can answer please ask, Thank you
Posted
by
Post not yet marked as solved
0 Replies
75 Views
Currently I'm using UIImagePickerController to allow our users to take photos within the app like so: UIImagePickerController *picker = [UIImagePickerController new]; picker.sourceType = UIImagePickerControllerSourceTypeCamera; picker.mediaTypes = @[(NSString *)kUTTypeImage]; picker.delegate = self; [self presentViewController:picker animated:YES completion:nil]; And I use the delegate method to get the image out and do what is needed: -(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info { // Do stuff. } This seems to work fine for 99.9% of our users but for some reason we occasionally have an odd info dictionary with no image in it. When I print the info dictionary, it looks like this every time: {    UIImagePickerControllerMediaMetadata =     {        "{MakerApple}" =         {            25 = 0;        };    };    UIImagePickerControllerMediaType = "public.image"; } As you can see there is no UIImagePickerControllerEditedImage or UIImagePickerControllerOriginalImage in that dictionary. Anyone have any ideas on what this is, and what I might be able to do to 'fix it' ?
Posted
by