Post

Replies

Boosts

Views

Activity

Why the show/ hide table view mechanism doesn't work in non iPhone SE simulator?
I am using the following mechanism, to perform UITableView's row show and hide. class TableViewController: UITableViewController { private var hiddenIndexPaths : Set<IndexPath> = [] override func viewDidLoad() { super.viewDidLoad() } @IBAction func toggle(_ sender: UISwitch) { if sender.isOn { show(1) show(2) } else { hide(1) hide(2) } tableView.beginUpdates() tableView.endUpdates() } private func isHidden(_ indexPath: IndexPath) -> Bool { hiddenIndexPaths.contains(indexPath) } private func hide(_ item: Int) { hiddenIndexPaths.insert(IndexPath(item: item, section: 0)) } private func show(_ item: Int) { hiddenIndexPaths.remove(IndexPath(item: item, section: 0)) } override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { if isHidden(indexPath) { return 0.0 } return super.tableView(tableView, heightForRowAt: indexPath) } } As you can see, it works great in iPhone SE simulator (Works well in iPhone SE real device too) iPhone SE simulator linkText However, in non iPhone SE simulator (Like iPhone 13), once the table row is hidden, it can no longer be shown. Please refer to the following video. iPhone 13 simulator I am not sure what will its behavior in iPhone 13 real device, because I do not have access. I was wondering, do you have any idea why such issue occurs? If you are interested to test, here's the complete workable sample - https://github.com/yccheok/show-hide-table-row-bug
Topic: UI Frameworks SubTopic: UIKit Tags:
4
0
1.1k
Sep ’22
What is a reliable way, to check user system locale is using 12-hours or 24-hours format?
We would like to know, whether a user system locale is using 12-hours or 24-hours format? There are many proposed solutions at https://stackoverflow.com/q/1929958/72437 One of the solutions are let formatString = DateFormatter.dateFormat(fromTemplate: "j", options: 0, locale: Locale.current)! let hasAMPM = formatString.contains("a") However, to me, this is not a correct solution. When I tested with de_DE (German is using 24-hours), the returned string is HH 'Uhr' What is Uhr mean for? I guess it mean "clock" in German? There are so many other locales and one of them might contain letter a. Does anyone know, what is a correct way, to check whether user system locale is using 12-hours or 24-hours format?
3
0
841
Feb ’23
The following simple function will cause Xcode 12E262 to have "Abort: trap 6"
The following simple function will cause Xcode 12E262 to have "Abort: trap 6" during compilation. import UIKit import CoreData class ViewController: UIViewController {     func xyz() {         let container = NSPersistentContainer(name: "xyz")         let batchUpdateRequest = NSBatchUpdateRequest(entityName: "xyz")         let batchUpdateResult = try! container.viewContext.execute(batchUpdateRequest) as? NSBatchUpdateResult         guard let batchUpdateResult = batchUpdateResult else { return }     }     override func viewDidLoad() {         super.viewDidLoad()         // Do any additional setup after loading the view.     } } We will not observe "Abort: trap 6", if under Build Settings, we are using "Optimize for Speed" in Debug, instead of "No Optimization" We can also avoid "Abort: trap 6", if we change the following code guard let batchUpdateResult = batchUpdateResult else { return } to guard let batchUpdateResult2 = batchUpdateResult else { return } May I know, why is it so? A simpler code example to reproduce problem, without CoreData would be import UIKit class ViewController: UIViewController {     func getAny() throws -> Any? {         return nil     }     func xyz() {         let name = try! getAny() as? UIViewController         guard let name = name else { return }     }     override func viewDidLoad() {         super.viewDidLoad()         // Do any additional setup after loading the view.     } }
2
0
943
Jun ’21
Prevent scroll position from resetting when perform UITextView typing in UICollectionView
Currently, we try to place multiple UITextViews in UICollectionView. To ensure UICollectionView's cell height, will adjust based on the dynamic content of UITextView, this is what we have done. Disable scrolling in UITextView. Use .estimated(CGFloat(44)) for UICollectionViewCompositionalLayout Whenever there is text change, call collectionView.collectionViewLayout.invalidateLayout(). This is a critical step to ensure cell height will adjust accordingly. However, calling collectionView.collectionViewLayout.invalidateLayout() does come with a side effect. The current scroll position of UICollectionView will be reset, after calling collectionView.collectionViewLayout.invalidateLayout(). Does anyone know how can I Prevent unwanted auto scroll position resetting? UICollectionView will auto scroll to current cursor position, so that what is current being typed is visible to user? The code to demonstrate this problem is as follow - https://github.com/yccheok/checklist-demo Here's the code snippet, on what was happening as typing goes on func textViewDidChange(_ checklistCell: ChecklistCell) { // // Critical code to ensure cell will resize based on cell content. // // (But comes with a side effect which will reset scroll position.) self.collectionView.collectionViewLayout.invalidateLayout() // // Ensure our checklists data structure in sync with UI state. // guard let indexPath = collectionView.indexPath(for: checklistCell) else { return } let item = indexPath.item let text = checklistCell.textView.text self.checklists[item].text = text } Side Note Note, the closest solution we have came across is posted at https://medium.com/@georgetsifrikas/embedding-uitextview-inside-uitableviewcell-9a28794daf01 In UITableViewController, during text change, the author is using DispatchQueue.main.async { tableView?.beginUpdates() tableView?.endUpdates() } It works well. But, what is the equivalent solution for UICollectionView? We can't try out with self.collectionView.performBatchUpdates, as our solution is built around Diffable Data Source. I have tried DispatchQueue.main.async { self.collectionView.collectionViewLayout.invalidateLayout() } That doesn't solve the problem either. Thank you.
Topic: UI Frameworks SubTopic: UIKit Tags:
2
0
4.2k
Nov ’21
Is using CoreData + CloudKit to store text notes, and iCloud Document to store note image attachments as image files a good design approach?
Is using CoreData + CloudKit to store text notes and iCloud Document to store note image attachments as image files a good design approach? Currently, I have almost finished implementing the app to store text notes as Core Data and note image attachments as image files. I like to provide iCloud storage support to the app. I come across a few app examples https://www.raywenderlich.com/13219461-getting-started-with-core-data-and-cloudkit https://developer.apple.com/documentation/coredata/synchronizing_a_local_store_to_the_cloud Both examples are using CoreData + CloudKit to store the image as SQLite blob binary data which CoreData will perform such task automatically) I'm aware that when storing the binary image into CoreData, CoreData is smart enough to choose either to store it as a binary blob in SQLite, or an external file. However, I am a little skeptical about such an approach We are using Kingfisher for smooth image loading in the collection view. If the image data are not in a regular flat-file, how can we integrate CoreData's blob data with Kingfisher? Storing images in CoreData seems like a black box. If something goes wrong in between, it is hard to debug where and how goes wrong. We like to provide alternative cloud storage (using cloud S3 storage to store SQLite files and multiple images) for the app. So, saving the image as flat files will make such an effort easier. Some related discussion on storing the image in DB vs flat files - https://stackoverflow.com/questions/3748/storing-images-in-db-yea-or-nay I would prefer Only use CoreData + CloudKit to store the text note and file path. The image file will store in both the app folder and the iCloud document folder (so that it syncs seamlessly to iCloud). If the required images are not in the app folder (App uninstall, then re-install), the app will try to copy the image file from the iCloud document I was wondering, anyone of you has tried such a design in your app? Do you find it is a good approach based on your experience? Thanks.
2
0
1.1k
Apr ’22
Why SFSymbol "face.smiling" will changed to "face.smiling.fill" when switching to dark mode.
I am using XCode 14. The following is the UIImageView, using SFSymbol face.smiling UIImageView background is pink color UIImageView tint is black color When I switch my app to dark mode, the smiling face which use to be transparent color, has became solid black color. The face line (eye, mouth, face border) used to be solid black color, had became transparent color. It seems like the image has changed from "face.smiling" to "face.smiling.fill" ? I would like to avoid such outcome. Is there a way, to force UIImageView load SFSymbol in light mode, even though the entire app is using dark mode? (This happens same when I test using real device and simulator) Thanks.
Topic: Design SubTopic: General Tags:
2
1
1.9k
Sep ’22
WidgetKit iOS 17 : Interactive widget no longer responsive after a long idle time
I have developed an interactive widget which looks as the following It is using CoreData. The view is implemented as the following struct widget_extensionEntryView : View { var body: some View { if let nsTodoList = nsTodoList { VStack(alignment: .leading, spacing: 1) { ... ForEach(0..<prefixGoodNSTodoArray.count, id: \.self) { index in ... let todoIntent = TodoIntent(objectIDAsString: objectIDAsString, parentOrder: parentOrder) Button(intent: todoIntent) { } } } } } } The AppIntent is implemented as the following import Foundation import AppIntents import WidgetKit import CoreData struct TodoIntent: AppIntent { static var title: LocalizedStringResource = "Complete Task" static var description: IntentDescription = IntentDescription("Complete selected task") @Parameter(title: "objectIDAsString") var objectIDAsString: String @Parameter(title: "parentOrder") var parentOrder: Int init() { } init(objectIDAsString: String, parentOrder: Int) { self.objectIDAsString = objectIDAsString self.parentOrder = parentOrder } func perform() async throws -> some IntentResult { guard let objectID = NSManagedObjectID.from(objectIDAsString) else { return .result() } guard let nsTodoList = NSTodoListRepository.INSTANCE.getNSTodoList(objectID) else { return .result() } nsTodoList.toggleChecked(context: CoreDataStack.INSTANCE.viewContext, parentOrder: Int64(parentOrder)) RepositoryUtils.saveContextIfPossible(CoreDataStack.INSTANCE.viewContext) TodoWidgetOptions.isWrittenByWidgetExtension = true // Refresh all home widgets. // TODO: https://developer.apple.com/forums/thread/721937 WidgetCenter.shared.reloadAllTimelines() return .result() } } The interactive widget works pretty well. However, tapping on the widget has no response in the following situations: After an overnight, we turn on the iPhone's screen and tap on the widget. After a few hours of idle time, we turn on the iPhone's screen and tap on the widget. One of the steps below will make the widget workable again: Launch and close the main app again. The main app will call WidgetCenter.shared.reloadAllTimelines() during sceneDidEnterBackground. Press and hold on the widget, choose 'Edit widget', and select the desired Todo list. One thing to take note of is that I am using IntentTimelineProvider instead of AppIntentTimelineProvider. The reason I am using 'older tech' is due to the limitation mentioned in https://developer.apple.com/forums/thread/741053 However, I am not sure whether this is the root cause of the problem. Does anyone have any idea why such a problem occurs? Thanks.
2
1
1.4k
Nov ’23
Not able login to simulator using the newly created sandbox account
I wish to login simulator using a sandbox account so that I can test on in-app purchase and subscription. I have created a new apple id account using a new email. I have confirmed the new apple id + password is correct, by login into https://appleid.apple.com/#!&page=signin I also added the new apple id account into App Store Connect as sandbox tester - However, I am still not able login to simulator. I am keep getting error - "Username or password is incorrect" You can see in the simulator background. I can login to https://appleid.apple.com/#!&page=signin using the new apple id + password via web browser. But, I am not sure why I am not able login into the simulator itself. Can anyone assist me on this? Thank you.
2
4
2k
Mar ’24
In-App Purchase Review Delaying App Release - Next Steps?
Our submitted binary app version has been approved by Apple reviewers. It's currently pending Developer Release. However, our in-app purchase, which was submitted at the same time, is still under review. Since the newly added in-app purchase hasn't been approved yet, we've decided to hold off on releasing the binary app version. Should we just wait for Apple to approve the in-app purchase, or are there any other recommended actions? Thank you.
2
0
773
Jun ’24
How to deal with Guideline 2.1 - Information Needed (App Tracking Transparency framework related)
My app, which only shows ads one day after it is first launched, keeps being rejected due to Guideline 2.1 - Information Needed (App Tracking Transparency framework related). Here is the rejection message from Apple: Guideline 2.1 - Information Needed We're looking forward to completing our review, but we need more information to continue. Your app uses the AppTrackingTransparency framework, but we are unable to locate the App Tracking Transparency permission request when reviewed on iOS 17.5.1. Next Steps Please explain where we can find the App Tracking Transparency permission request in your app. The request should appear before any data is collected that could be used to track the user. If you've implemented App Tracking Transparency but the permission request is not appearing on devices running the latest operating system, please review the available documentation and confirm App Tracking Transparency has been correctly implemented. If your app does not track users, update your app privacy information in App Store Connect to not declare tracking. You must have the Account Holder or Admin role to update app privacy information. We have provided a detailed step-by-step guide to trigger the App Tracking Transparency. We also attached videos demonstrating how to adjust the date to one day ahead in order to show the ads. Here is our reply: Dear Reviewer, XXX will start displaying ads one day after the app is first launched. To see the App Tracking Transparency permission request and subsequent ads, please follow these steps: 1. Launch XXX for the first time. 2. Close and completely exit the XXX app. 3. Adjust the date on your device to one day ahead. 4. Re-launch XXX. You will see the App Tracking Transparency permission request. For a visual guide, please refer to the attached videos: https://youtube.com/shorts/07qsYuFkPBY - Demonstrates when the user allows tracking. https://youtube.com/shorts/voQfgjAN7h0 - Demonstrates when the user does not allow tracking. If you need further explanation, please contact me at +xxxx-xxxxxxx. Thank you. P.S. I frequently receive similar inquiries with each submission of my app. Could you please add a note to my app to prevent this recurring issue in future reviews? Thank you for your attention. However, Apple continues to reject our update, despite our clear instructions for showing App Tracking Transparency. Do you have any suggestions on what we can do next? Thank you.
2
0
1.4k
Jul ’24
Resolving 2nd Repeated "Guideline 4.3(a) - Design - Spam" Rejection Within Six Months
We are reaching out for guidance after encountering 2nd repeated "Guideline 4.3(a) - Design - Spam" rejections for our WeNote app. Here’s a brief timeline of our journey: 2018: We launched the WeNote Android app on Google Play Store. 2019: We started promoting WeNote on YouTube and began development of the WeNote iOS app. Our progress was publicly visible on our Trello board and discussed on the Apple Developer forum. August 17, 2021: We filed an official complaint with Apple regarding a *** company infringing on our app logo, title, and description. The issue was resolved when *** agreed to update their app’s branding. 2022 Year: *** company is terminated from App Store. June 2022: WeNote for iOS was officially released on the Apple App Store. June 17, 2024: We received a rejection from the Apple Review team citing Guideline 4.3(a) - Design - Spam: “We noticed your app shares a similar binary, metadata, and/or concept as apps previously submitted by a terminated Apple Developer Program account. Submitting similar or repackaged apps is a form of spam that creates clutter and makes it difficult for users to discover new apps.” We successfully resolved this issue by providing documentation about the previous incident on August 17, 2021. November 22, 2024: Unfortunately, we received the same rejection message again, despite having already informed Apple of the previous case. Request for Assistance: We are now seeking guidance from the community or anyone with experience in navigating similar issues. We’ve provided Apple with all the necessary evidence and explanations regarding the previous incident, but our appeal was rejected. How can we resolve this issue, and prevent future rejections? Some Background on WeNote: To help provide context, I’d like to highlight what makes WeNote stand out compared to other apps in the same category: WeNote is an all-in-one solution: While most apps in the market focus on one function—whether it’s note-taking, to-do lists, or calendar management—WeNote uniquely combines all three into a single app. This integration offers users a seamless experience to manage tasks, notes, and schedules in one place. Proven user satisfaction: We are proud to have over 7,000 user reviews, with an average rating of 4.8 stars. This high rating reflects our users' satisfaction with the app’s features and functionality, as well as its ability to meet their needs in a way that other apps do not. We believe these features make WeNote a valuable and unique tool for users, and we continue to prioritize quality and user experience in our development.
2
0
629
Dec ’24
How to animate substring in a Text?
Currently, I am using multiple Texts in a horizontal stackview, to achieve animation of substring. As you can see in the above animation, the text - conversation - meeting - lecture are animated. However, there shortcoming of such an approach. Text size is not consistent among different Text block. The following Text block are having different text size. - Transform - conversation/ meeting/ lecture - to Quick Note Any idea how we can achieve, so that all text blocks have same text size so that they appear like 1 sentence? Or, how we can make the text blocks having constant text size, but able to perform line wrapping to next line, so that they appear like 1 sentence? Currently, this is the code snippet I am using. import SwiftUI struct ContentView: View { var array = ["lecture", "conversation", "meeting"] @State var currentIndex : Int = 0 @State var firstString : String = "" var body: some View { VStack { HStack { Text("Transform") .lineLimit(1) .minimumScaleFactor(0.5) .font(.title) Text(firstString) .lineLimit(1) .minimumScaleFactor(0.5) .font(.title) .transition(AnyTransition.opacity.animation(.easeInOut(duration:1.0))) .background(.yellow) Text("to Quick Note") .lineLimit(1) .minimumScaleFactor(0.5) .font(.title) }.padding() } .animation(.default) .onAppear { firstString = array[0] let timer = Timer.scheduledTimer(withTimeInterval: 2.0, repeats: true) { _ in if currentIndex == array.count - 1 { self.firstString = array[0] currentIndex = 0 } else { self.firstString = array[currentIndex+1] currentIndex += 1 } } } } } #Preview { ContentView() }
2
0
412
Dec ’24
Managing Legacy Subscriptions on the App Store
I have several subscription plans in the App Store that I no longer wish to offer to new users. In my app, these old subscriptions are hidden, but they remain active so existing subscribers can continue their plans and be charged as usual. However, some new users are still able to switch to these old subscription plans through the App Store. What is the best solution for this situation? I want to continue serving existing subscribers while preventing new users from subscribing to these legacy plans. Thank you.
2
0
234
Sep ’25