Post

Replies

Boosts

Views

Activity

Extra Branch in Xcode Source Control Pane
I merged two branches with different feature sets. I branched from one of the two then merged in the second (using command line and file merge). Now in Xcode's source control pane it shows two different branches as current. It's not a big deal but I would like to know how to get rid of the top one (at the very least) and preferably to understand why both would be displayed as current. It makes pushing to remotes a bit of a headache because they have the same app name and so I need to make sure I don't push to the wrong branch. I don't particularly want to have to redo things a different way since the branches had a fair number of merge conflicts. Also, if I use Xcode to commit, a bunch of extra files ending with .orig come up as well as many .pbxproj files that I cannot find when I search my file directory.
1
0
1.1k
Jul ’21
SwiftUI TabView Off-Screen Tabs Not Redrawing.
Running into a weird issue with TabViews not rerendering the view when objectWillChange.send() is called (either manually or with @Published). For context, in my real project I have a tab with form data and the adjacent tab is a summary tab which renders a few elements from the form data. The summary tab is not getting updated when the form data changes. I have created a simple demo project that demonstrates the issue. The project can be found here. The content view is just a tab view with four tabs, all of which point to the same core data object. struct ContentView: View {     @Environment(\.managedObjectContext) private var viewContext     @State private var selectedIndex: Int = 0     var tabTitles: Array<String> = ["Tab 1", "Tab 2", "Tab 3", "Tab 4"]     var body: some View {         // Create a page style tab view from the tab titles.         TabView(selection: $selectedIndex) {             ForEach(tabTitles.indices, id: \.self) { index in                 TextView(viewModel: TextViewModel(                     title: tabTitles[index],                     context: viewContext))             }         }         .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))     } } The text view just contains the title and a text field for updating the core data object in the view model. struct TextView: View {     @ObservedObject private var viewModel: TextViewModel     @State private var text: String     private var relay = PassthroughSubject<String, Never>()     private var debouncedPublisher: AnyPublisher<String, Never>     init(viewModel: TextViewModel) {         self.viewModel = viewModel         self._text = State(initialValue: viewModel.textValue)         self.debouncedPublisher = relay             .debounce(for: 1, scheduler: DispatchQueue.main)             .eraseToAnyPublisher()     }     var body: some View {         LazyVStack {             Text(viewModel.title)                 .font(.title)             TextField("write something", text: $text)                 .onChange(of: text) {                     relay.send($0)                 }         }         .padding()         .onReceive(debouncedPublisher) {             viewModel.textValue = $0         }         /// Without this the view does not update, with it the view updates properly...         .onAppear {             self.text = viewModel.textValue         }     } } And the view model is pretty simple. I've tried making item @Published, I've tried making the text value computed (with @Published item), etc. This example uses a combine publisher on item's value attribute which is a lot like what I'm doing in the main project. class TextViewModel: ObservableObject {     @Published var textValue: String {         didSet {             // Check that the new value is not the same as the current item.value or else an infinte loop is created.             if item.value != textValue {                 item.value = textValue                 try! context.save()             }         }     }     private(set) var item: Item     private(set) var title: String     private var subscriber: AnyCancellable?     private var context: NSManagedObjectContext     init(title: String, context: NSManagedObjectContext) {         self.title = title         self.context = context         let request = NSFetchRequest<Item>(entityName: "Item")         request.predicate = NSPredicate(format: "%K == %@", #keyPath(Item.key), "key")         request.sortDescriptors = [NSSortDescriptor(key: #keyPath(Item.value), ascending: true)]         let fetched = try! context.fetch(request)         let fetchedItem = fetched.first!         self.textValue = fetchedItem.value!         self.item = fetchedItem         // Create a publisher to update the text value whenever the value is updated.         self.subscriber = fetchedItem.publisher(for: \.value)             .sink(receiveValue: {                 if let newValue = $0 {                     self.textValue = newValue                 }             })     } } Item is just a simple core data property with a key: String and value: String. I know I can directly bind the view to to the text value using $viewModel.textValue. It doesn't update the view when the value changes either and I don't want that behavior in my real app for a variety of reasons. Is there something that I am missing here? Do I really need to call onAppear for all of my views within the TabView to check and see if the value is up-to-date and update it if needed? It seems a bit silly to me. I haven't really found much info out there on this. I've also tried forcing a redraw using the (super yucky) use of @State var redraw: Bool and toggling it in onAppear. That does not trigger a redraw either. The other thing I've tried that works is setting an @State isSelected: Bool on the TextView and in the ForEach setting it to index == selectedIndex. This works and may be the least revolting solution I have found. Thoughts?
1
0
2.1k
Apr ’22
Collection View Bug - Shadow insert is nil. File a bug on UICollectionView
Our app uses a number of collection views in a single iPad screen for the user to set the location of various resources. There is a main group for unassigned resources and up to 16 UICollectionView's that represent a job for the resource. The user can manage their resources by dragging a resource between any of the collection views. This generally works but periodically after dragging back and forth many times we get the following runtime exception: Shadow insert is nil. File a bug on UICollectionView! When I search for this error I get no results. The drag and drop implementation is as follows: public func collectionView(_ collectionView: UICollectionView, canHandle session: UIDropSession) -> Bool { if !singleUseCollectionViews.contains(collectionView){ return true } guard let containerProperties = getResourceContainer(collectionView: collectionView) else { return false } return viewModel.canResourceBeDropped(containerToDropTo: containerProperties) } public func collectionView(_ collectionView: UICollectionView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UICollectionViewDropProposal { currentDestinationIndexPath = destinationIndexPath // Copy is being used to add the green plus icon when user is dropping item into the other collectionview. return UICollectionViewDropProposal(operation: .copy, intent: .insertAtDestinationIndexPath) } public func collectionView(_ collectionView: UICollectionView, performDropWith coordinator: UICollectionViewDropCoordinator) { defer { viewModel.isUserDraggingResource = false } guard let containerToDropTo = getResourceContainer(collectionView: collectionView, sectionIndex: 0) else { print("Attempting to drop where resource cannot be dropped") assertionFailure() return } if let resourceToDrop = self.viewModel.resourceToDrop { self.viewModel.addNewResourceToGroup(resource: resourceToDrop, containerProperties: containerToDropTo, userInitiated: true) } else if self.viewModel.personnelToDrop != nil { self.viewModel.formNewResourcesWithDroppedPersonnel(containerToDropTo: containerToDropTo) } resourceDropped() } public func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] { guard viewModel.boardIsActive else { return [] } guard let stringData = "test".data(using: .utf8) else { return [] } guard let containerToDropFrom = getContainer(collectionView: collectionView, sectionIndex: indexPath.section) else { return [] } viewModel.prepareToDropFrom(index: indexPath.row, containerProperties: containerToDropFrom) let itemProvider = NSItemProvider(item: stringData as NSData, typeIdentifier: "WorksheetCell" as String) let dragItem = UIDragItem(itemProvider: itemProvider) session.localContext = (indexPath, collectionView) return [dragItem] } public func collectionView(_ collectionView: UICollectionView, dragSessionDidEnd session: UIDragSession) { viewModel.isUserDraggingResource = false collectionView.endInteractiveMovement() } } We see this crash in production and test on physical devices. I have yet to see it on the simulator, however under similar circumstances the simulator has simply crashed with no info in Xcode. When that happens, the following stack trace is presented by Mac OS. Translated Report (Full Report Below) OS Version:         macOS 13.0 (22A380) Release Type:       User Report Version:     104Exception Type: EXC_CRASH (SIGABRT) Exception Codes: 0x0000000000000000, 0x0000000000000000 Triggered by Thread: 0Last Exception Backtrace: 0  CoreFoundation                       0x10fa668bb __exceptionPreprocess + 226 1  libobjc.A.dylib                      0x10d49fba3 objc_exception_throw + 48 2  Foundation                           0x11164137c _userInfoForFileAndLine + 0 3  UIKitCore                            0x124f3c65e -[_UICollectionViewDragAndDropController _beginDragAndDropInsertingItemAtIndexPath:] + 639 4  UIKitCore                            0x124f3a699 -[_UICollectionViewDragAndDropController beginReorderingForItemAtIndexPath:cell:] + 281 5  UIKitCore                            0x124eee108 -[UICollectionView _beginInteractiveMovementForItemAtIndexPath:] + 263 6  UIKitCore                            0x124f479c9 -[_UICollectionViewDragDestinationController _reorderingDisplayLinkDidTick] + 1545 7  QuartzCore                           0x10f4b200f CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long) + 923 8  QuartzCore                           0x10f5d7aa9 display_timer_callback(__CFMachPort*, void*, long, void*) + 395 9  CoreFoundation                       0x10f991c9f __CFMachPortPerform + 151 10 CoreFoundation                       0x10f9c6844 CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION + 41 11 CoreFoundation                       0x10f9c5d8b __CFRunLoopDoSource1 + 538 12 CoreFoundation                       0x10f9c0588 __CFRunLoopRun + 2740 13 CoreFoundation                       0x10f9bf6f7 CFRunLoopRunSpecific + 560 14 GraphicsServices                     0x11659228a GSEventRunModal + 139 15 UIKitCore                            0x1259b162b -[UIApplication _run] + 994 16 UIKitCore                            0x1259b6547 UIApplicationMain + 123 17 IncidentIntelligenceSystem           0x100a568ff main + 63 (AppDelegate.swift:23) 18 dyld_sim                             0x10ad082bf start_sim + 10 19 dyld                                 0x202a52310 start + 2432Kernel Triage: VM - pmap_enter retried due to resource shortage VM - pmap_enter retried due to resource shortage VM - pmap_enter retried due to resource shortage VM - pmap_enter retried due to resource shortage VM - pmap_enter retried due to resource shortage Any help would be greatly appreciated.
1
0
769
Dec ’22
SwiftUI Text Editor Crash with Apple Pencil Long Press
Using Apple Pencil with SwiftUI text editor, when the user presses and holds in the middle of text already in the editor box a crash occurs. This is very reproducible even on this minimal example. import SwiftUI struct ContentView: View { @State private var text: String = "The quick brown fox jumps over the lazy dog" var body: some View { VStack { TextEditor(text: $text) .background(Color.init(red: 242, green: 242, blue: 242)) .border(.black) .frame(height: 200) } .padding() } } When tapping and holding somewhere in the middle of the sentence, for example on the word "jumps" the app crashes with an exception reading: Thread 1: "NSTextContentStorage: Inconsistent element cache state. Elements for range {0, 43} are already cached while trying to insert" The stack trace is: I have attempted to use the approach discussed in this post to make the underlying UITextView use TextKit 1, but could find no UITextView in the underlying UIView hierarchy. Any advice would be greatly appreciated.
2
3
1.7k
Jan ’23