【问题标题】:SwiftUI Nav Bar cut offSwiftUI 导航栏被切断
【发布时间】:2020-04-27 05:36:20
【问题描述】:

我最近更新了 Xcode,由于某种原因,现在在模拟器(和设备上)我的 SwiftUI 视图上的导航栏被切断,如下图所示:

我没有更改任何代码,所以我想知道到底发生了什么。该视图的代码供参考如下:

struct EventsView: View {
    @ObservedObject var viewModel: EventsViewModel

    init() {
        viewModel = EventsViewModel()
        coloredNavAppearance.configureWithOpaqueBackground()

        coloredNavAppearance.backgroundColor = ColorCodes.darkGrey.uicolor()
        coloredNavAppearance.titleTextAttributes = [.foregroundColor: UIColor.white]
        coloredNavAppearance.largeTitleTextAttributes = [.foregroundColor: UIColor.white]

        UINavigationBar.appearance().standardAppearance = coloredNavAppearance
        UINavigationBar.appearance().scrollEdgeAppearance = coloredNavAppearance

        UINavigationBar.appearance().tintColor = .white

        UITableView.appearance().separatorStyle = .none

    }

    var body: some View {
        NavigationView {
            if viewModel.eventViewModels.isEmpty {
                ZStack {
                    ColorCodes.darkGrey.color()
                        .edgesIgnoringSafeArea(.all)
                    VStack {
                    Text("No events are active yet. Click the plus button to purchase an event.").foregroundColor(.white).font(.custom("Segoe UI", size: 17))
                    }.navigationBarTitle(Text("Active Events"), displayMode: .large)
                    .navigationBarItems(trailing:
                        Button(action:  {
                            //show add event modal
                            self.viewModel.showAddEventModal.toggle()
                        }) {
                            Image("plus")
                        }
                    )
                }

            }else {
                List{

                    ForEach(viewModel.eventViewModels, id: \.id) { eventViewModel in
                        EventRow(viewModel: eventViewModel)
                    }.listRowBackground(ColorCodes.darkGrey.color())
                }
                .navigationBarTitle(Text("Active Events"), displayMode: .large)
                .navigationBarItems(trailing:
                    Button(action:  {
                        //show add event modal
                        self.viewModel.showAddEventModal.toggle()
                    }) {
                        Image(systemName: "plus")
                    }
                )
                .alert(isPresented: $viewModel.showAlert) {
                    Alert(title: Text("Error"), message: Text(viewModel.errorMessage), dismissButton: .default(Text("Ok")))
                }
                .sheet(isPresented: $viewModel.showAddEventModal) {
                    AddEventView(viewModel: AddEventViewModel())
                }

            }
        }
    }
}

这是一个事件的样子:

struct Event: Codable, Identifiable {

    public let id: String
    public let name: String
    public let phoneNumber: PhoneNumber
    public let isActive: Bool
    public let startDate: Date



    enum CodingKeys: String, CodingKey {
        case id = "id"
        case name = "name"
        case phoneNumber = "event_phone_number"
        case startDate = "start"
    }

}

这是事件视图模型:

import Combine

enum EventViewModelState {
    case loading
    case finishedLoading
    case error(Error)
}

class EventsViewModel: ObservableObject {

    @Published private(set) var eventViewModels: [EventCellViewModel] = []

    @Published private(set) var state: EventViewModelState = .loading

    @Published var errorMessage: String = ""

    @Published var showAlert: Bool = false

    @Published var showAddEventModal: Bool = false

    private var getEventsCancellable: AnyCancellable?

    private let eventService: EventServiceProtocol

    init(eventService: EventServiceProtocol = EventService()) {
        self.eventService = eventService
        getEvents()
    }

    func getEvents() {
        state = .loading

        getEventsCancellable = eventService
            .getEvents()
            .sink(receiveCompletion: { [weak self] (completion) in
                switch completion {
                case .failure(let serviceError):
                    if let errorCasted = serviceError as? ServiceError {
                    self?.unWrapError(error: errorCasted)
                    self?.state = .error(serviceError)
                    self?.showAlert = true
                    }
                case .finished: self?.state = .finishedLoading
                }
            }) { [weak self] events in
                self?.eventViewModels = events.map {
                    EventCellViewModel(event: $0)
                }
        }
    }

    func unWrapError(error: ServiceError) {
        switch error {
        case .url:
            self.errorMessage = "There was something wrong with the url request, please contact support."
        case .urlRequest:
             self.errorMessage = "There was something wrong with the url request, please contact support."
        case .decode:
             self.errorMessage = "There was something wrong with the response. Please make sure you are on the latest version of the app or contact support."
        case .internalError(let errorString):
             self.errorMessage = errorString
        }
    }
}

这里是事件单元视图模型:

import Foundation
import Combine

class EventCellViewModel: ObservableObject {

    @Published var name: String = ""
    @Published var eventPhoneNumber: String = ""
    @Published var startDate: String = ""
    @Published var id: String = ""

    private let event: Event

    init(event: Event) {
        self.event = event
        setUpBindings()
    }

    func setUpBindings() {
        id = String(event.id)
        name = event.name
        eventPhoneNumber = event.phoneNumber.phoneNumber
        startDate = event.startDate.toShortDate()
    }
}

我确实在类的 init 中设置了一些自定义导航栏外观设置,但这之前工作得很好。这是否发生在其他人身上,是否有人找到或想出解决方法?此外,正如您在下面看到的那样,这里有一个项目,它进入了我视图的 else 块,而不是您看到 ZStack 的 if,所以这不是我和其他人之前认为的问题。我也尝试过完全删除该部分,但仍然会发生这种情况。

【问题讨论】:

  • 你能提供最小的可重现示例吗,因为提供的快照不能按原样测试,所以对我有用的对你不起作用。
  • 更新了我的示例以包含更多详细信息/支持类@Asperi
  • 另外值得注意的是,Xcode 中的预览模式确实可以正确显示,但在模拟器或设备上却无法正确显示。

标签: ios swift xcode swiftui


【解决方案1】:

这能解决你的问题吗:

            .navigationBarItems(trailing:
                Button(action:  {
                    //show add event modal
                    self.viewModel.showAddEventModal.toggle()
                }) {
                    Image(systemName: "plus")
                }
            )

【讨论】:

  • 遗憾的是它没有:(
【解决方案2】:

想通了。不知何故这一行

.edgesIgnoringSafeArea(.top)

被添加到我的标签视图中并导致所有问题。

【讨论】:

    猜你喜欢
    • 2013-09-17
    • 1970-01-01
    • 2023-03-17
    • 2020-11-05
    • 2016-07-28
    • 1970-01-01
    • 1970-01-01
    • 2020-06-24
    • 1970-01-01
    相关资源
    最近更新 更多