#ios #swift #swiftui
#iOS #swift #swiftui
Вопрос:
Я пытаюсь создать приложение для ios (в ios 14), которое реагирует на изменения в текущих классах размеров. В частности, у меня есть модель данных, для которой я хочу установить разные значения на основе классов размера представления. Мне труднее всего понять, как это сделать.
Чтобы было ясно — я не хочу что-то менять в представлении на основе класса размера. Я хочу что-то изменить в модели данных, которая, по моему скромному мнению, не должна «знать» о представлении.
Я пытаюсь установить onChange
обработчик в своем корневом представлении в SwiftUI, но не могу придумать правильное заклинание, чтобы изменение любого из классов размера (horiz / vert) вызывало срабатывание моего onChange
обработчика.
Другими словами, я пытаюсь запустить произвольный код при изменении класса размера.
Если это имеет смысл для любого из гораздо более талантливых разработчиков ios на SO, пожалуйста, дайте мне знать. Если есть какая-либо дополнительная информация, которую я могу предоставить, пожалуйста, спросите.
Большое спасибо!
Комментарии:
1. Не могли бы вы показать свой код?
Ответ №1:
Вы можете использовать GeometryReader для обновления последней ширины / высоты пользовательского интерфейса до модели представления. При размещении встроенного оператора if внутри представления метод «vm.render» будет вызываться при каждом изменении размера GeometryReader. Кроме того, в отличие от .onAppear() этот оператор if вызывается при изменении ориентации.
Казалось гораздо менее сложным использовать GeometryReader со встроенным оператором if, чем подключать события ориентации с помощью: UIDevice.current.beginGeneratingDeviceOrientationNotifications() , плюс subscribe , плюс .onReceive(NotificationCenter.default.publisher …
Я совершенно уверен, что этот метод не вызывает небезопасный рендеринг контента, поскольку он блокирует все дочернее содержимое до тех пор, пока метод не будет оценен. Если кто-нибудь знает о проблеме с настройкой переменных во внешнем классе в середине визуализации, дайте мне знать. Это кажется до жути простым, пока что без недостатков.
import SwiftUI
fileprivate class viewModel: ObservableObject {
private var _uiLastSize:CGSize = CGSize(width:0, height:0)
public func render(_ size:CGSize) -> Bool {
guard size != CGSize.zero else {
return false
}
if size != _uiLastSize {
print("resize")
_uiLastSize = size
}
return true
}
}
struct TesterView: View {
@ObservedObject private var vm:viewModel
init() {
vm = viewModel()
}
var body: some View {
GeometryReader { geo in
if vm.render(geo.size) {
ZStack {
Color.blue
Text("Orientation: (geo.size.width > geo.size.height ? "landscape" : "portrait")")
}
}
}
}
}