Вопросы по Picker в SwiftUI (WatchOS)

watchos
swiftui

#1

Значит делаю приложение для часов и нужно расположить 2 пикера на экране, но после добавления пикера, все элементы съезжают наверх. Все находится в VStack и между группами элементов стоят спейсеры. Без пикера все работает как нужно.

Код
ZStack {
            VStack(alignment: .leading) {
                Text("Biceps Curl")
                    .font(.system(size: 14))

                HStack(alignment: .center) {
                    Text("Set 1/3")
                        .font(.system(size: 14))
                    
                    Spacer()
                    
                    Image("hr-icon-1")
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .frame(height: 14)
                    Text("135")
                        .font(.system(size: 14))
                }
                
                Spacer()

                HStack(spacing: 8) {
                    VStack {
                        Picker("", selection: $selected) {
                            ForEach(0 ..< 100) {
                                Text("\($0)")
                            }
                        }
                        .labelsHidden()
                        .frame(height: 44)

                        Text("kg")
                    }

                    VStack {
                        Picker("", selection: $selected2) {
                            ForEach(0 ..< 100) {
                                Text("\($0)")
                            }
                        }
                        .labelsHidden()
                        .frame(height: 44)

                        Text("rp")
                    }
                }
                .defaultWheelPickerItemHeight(38)
                
                Spacer()
                
                HStack(spacing: 8) {
                    Button {
                        
                    } label: {
                        Text("<-")
                            .frame(maxWidth: .infinity, minHeight: 44)
                            .background(RoundedRectangle(cornerRadius: 8).fill(Color.gray2))
                    }
                    .buttonStyle(.plain)
                    .frame(width: 56)
                    
                    Button {
                        
                    } label: {
                        Text("Start")
                            .frame(maxWidth: .infinity, minHeight: 44)
                            .background(RoundedRectangle(cornerRadius: 8).fill(.green))
                    }
                    .buttonStyle(.plain)
                }
            }
            .padding(.init(top: 36, leading: 16, bottom: 16, trailing: 16))
            .ignoresSafeArea()
            .background(Color.orange)
        }

В итоге выходит так
59

Если убрать пикеры, выходит так, все группы на своих местах, кнопки привязаны к низу
31

В итоге нужно сделать такой экран

Следующий вопрос касательно пикеров, как их кастомить в SwiftUI? Как убрать авто фокус при заходе на экран?
И еще вопрос: я смотрел как делать кастомные вьюхи через UIViewRepresentable, но у меня ругается на вью элементы из UIKit. Тут подозреваю что дело связано с WatchOS, т.к. он не поддерживает UIKit. Тогда вопрос, как сделать кастомную вью для часов? Делать это в таргете iOS?

Таргет для iOS 13.0 на UIKit
Таргет для WatchOS 7.4 на SwiftUI
Еще я сижу на М1 и в этом проекте не работает превью для SwiftUI. Если создать новый проект, превью работает.


#2

Привет по моему ZStack тебе не нужен тут.


#3

ZStack нужен для другого, я добавляю первым элементом пикер и прячу его, таким образом фокус срабатывает на него. Таким костылем получилось избавиться от фокуса на видимый пикер. Ну а сбрасывать фокус буду уже по таймеру, если нету действий от юзера.


#4

Попробуйте бэкграунд сделать не через модификатор, а в ZStack просто цвет сложить. Ещё можно поиграться с высотой фрейма не самого пикера, а Текста внутри него.


#5

К ZStack вопросов у меня нету. Все сложности именно с пикером. Фрейм пикера я пока оставил и добавил размер текста внутри пикера. Более-менее вроде сработало.
С фокусом я разобрался, но и тут через хак, как уже писал раньше.
Бордер пикера так же через хак обошел. Добавил оверлей с двумя RoundedRectangle. Первый прячет оригинальный бордер, второй рисует и меняет цвет от фокуса.
Кастомные вью получается совсем нельзя сделать на часах, т.к. там нету UIKit.
В общем SwiftUI сильно урезан на часах как я понял. На телефоне еще не пробовал.


#6

Про часы не скажу - ничего не делал. На iOS/MacOS проблем вообще нет (почти) с версии 3.0 (ios15)


#7

Там вместо UIKit идёт WatchKit с малым набором кастома. В SwiftUI вроде чуть больше возможностей