debugging SwiftUI中的奇怪行为:[UITextField聚焦时应用程序崩溃?]

ctehm74n  于 2023-03-30  发布在  Swift
关注(0)|答案(1)|浏览(133)

早上好,在我的生产应用程序中,我注意到在更改视图时我认为是一个错误(例如触发切换),如果在更改应用程序时UITextFieldFocused,则会崩溃。我能够重现此错误。这应该是这样吗?我真的需要防御性开发吗?
基本上,我点击AddCustomSource,文本字段出现添加自定义源。如果我点击取消或触发其中一个切换,而文本字段有焦点,应用程序将崩溃。100%可重现。
这里的错误,控制台显示:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Attempt to delete item containing first responder that refused to resign.
First responder that was asked to resign (returned YES from -resignFirstResponder): <UITextField: 0x13411bc00; frame = (0 0; 290 22); opaque = NO; autoresize = W+H; gestureRecognizers = <NSArray: 0x600002d66880>; placeholder = NewspaperTitle; borderStyle = None; background = <_UITextFieldNoBackgroundProvider: 0x6000021e5190: textfield=<UITextField 0x13411bc00>>; layer = <CALayer: 0x6000023568e0>> inside containing view: <SwiftUI.ListCollectionViewCell: 0x134151a00; baseClass = UICollectionViewListCell; frame = (20 82.6667; 358 44); clipsToBounds = YES; layer = <CALayer: 0x60000235d220>> at index path: <NSIndexPath: 0xae4395876dfb5f2e> {length = 2, path = 0 - 1}
Current first responder: <_TtGC7SwiftUI15CellHostingViewGVS_15ModifiedContentVS_14_ViewList_ViewVS_26CollectionViewCellModifier__: 0x134152000; frame = (0 0; 358 44); autoresize = W+H; gestureRecognizers = <NSArray: 0x600002d62f70>; layer = <CALayer: 0x60000235dc20>> inside containing view: <SwiftUI.ListCollectionViewCell: 0x134151a00; baseClass = UICollectionViewListCell; frame = (20 82.6667; 358 44); clipsToBounds = YES; layer = <CALayer: 0x60000235d220>> at index path: <NSIndexPath: 0xae4395876dfb5f2e> {length = 2, path = 0 - 1}'
terminating with uncaught exception of type NSException
CoreSimulator 857.14 - Device: iPhone 14 Pro Max (9E3E3FA5-4FCC-47D7-9D91-E1E5E48286FE) - Runtime: iOS 16.2 (20C52) - DeviceType: iPhone 14 Pro Max

下面是导致这种行为的代码:

//
//  ContentView.swift
//  BLE
//
//  Created by Entwicklung Help Tech GmbH on 22.12.22.
//

import SwiftUI
import CoreBluetooth


struct ContentView: View {
    @State var categories: [NewsSource] = []
    @State var isEditing = false
    @State var newSourceName = ""
    var body: some View {
        VStack {
            List($categories, id:\.self ) { $category in
                Section {
                    ForEach($category.sources, id: \.self ) { $source in
                        Toggle(source.name, isOn: $source.active)
                            .foregroundColor(Color.black)
                            .accessibilityLabel(String(localized: "s"))
                            .onChange(of: categories, perform: { newValue in
                                
                            })
                            .tint(Color.blue)
                        if !isEditing {
                            Button { [self] in
                                withAnimation(.spring()) {
                                    isEditing.toggle()
                                }
                            } label: {
                                HStack {
                                    Text(String(localized:"AddCustomSource"))
                                }
                            }
                        }
                        else {
                            AddCell
                            HStack {
                                Button { [self] in
                                    withAnimation(.spring()) {
                                        //isFocused = false
                                        isEditing.toggle()
                                    }
                                } label: {
                                    HStack {
                                        Text(String(localized: "Cancel"))
                                    }
                                }
                                Spacer()
                            }
                        }
                    }
                }
            header: {
                Text(category.name)
            }
            }
            .padding()
        }
        .onAppear {
            for index in 1...10 {
                categories.append(NewsSource(name: "\(index)", feeds: [NewsFeed(name: "News feed \(index)", url: URL(string: "https://google.de")!, active: true)]))
            }
        }
    }
    @ViewBuilder var AddCell: some View {
        VStack {
            HStack {
                Button { [self] in
                    if newSourceName != "" {
                        withAnimation(.spring()) {
                            isEditing.toggle()
                        }
                    }
                } label: {
                    Image(systemName: "plus")
                        .background(.green)
                        .clipShape(Circle())
                        .foregroundColor(.white)
                        .frame(width: 20.0, height: 20.0)
                }
                TextField(String(localized: "NewspaperTitle"),text: $newSourceName)
                    .onSubmit { [self] in
                        if newSourceName != ""{
                            newSourceName = ""
                            withAnimation(.spring()) {
                                isEditing.toggle()
                            }
                        }
                    }
            }
        }
    }
}
    
    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            ContentView()
        }
    }
    
    
    //
    //  Newspaper.swift
    //  Activator
    //
    //  Created by Entwicklung Help Tech GmbH on 20.02.23.
    //
    
    
    struct NewsSource: Codable, Hashable, Identifiable, Equatable {
        var id: UUID { UUID() }
        var name: String
        var sources: [NewsFeed]
        
        init(name: String, feeds: [NewsFeed]) {
            self.name = name
            self.sources = feeds
        }
        
        init(from decoder: Decoder) throws {
            let container = try decoder.container(keyedBy: CodingKeys.self)
            self.name = try container.decode(String.self, forKey: .name)
            self.sources = try container.decode([NewsFeed].self, forKey: .sources)
        }
        
        func hash(into hasher: inout Hasher) {
            hasher.combine(name)
        }
        
        static func ==(lhs: NewsSource, rhs: NewsSource) -> Bool {
            return lhs.name == rhs.name && lhs.sources == rhs.sources
        }
    }
    
    struct Newspaper: Codable, Hashable {
        var categories : [NewsSource]
    }
    
    struct NewsFeed: Codable, Equatable, Hashable, Identifiable {
        var id: UUID? {
            UUID()
        }
        
        let name: String
        let url: URL
        var active: Bool
        var image: String?
    }
72qzrwbm

72qzrwbm1#

删除所有的id:\.self,这是一个会导致崩溃的错误。

相关问题