SwiftUI Segmented Picker не переключается при нажатии на него

Я пытаюсь реализовать сегментированное управление с помощью SwiftUI. По какой-то причине Segmented Picker не переключается между значениями при нажатии на него. Я прошел много руководств, но не нашел отличий от своего кода:

struct MeetingLogin: View {
    @State private var selectorIndex: Int = 0

    init() {
        UISegmentedControl.appearance().backgroundColor = UIColor(named: "JobsLightGreen")
        UISegmentedControl.appearance().selectedSegmentTintColor = UIColor(named: "AlmostBlack")
        UISegmentedControl.appearance().setTitleTextAttributes([.foregroundColor: UIColor.white,
                                                                .font: UIFont(name: "OpenSans-Bold", size: 13)!],
                                                               for: .selected)
        UISegmentedControl.appearance().setTitleTextAttributes([.foregroundColor: UIColor.white,
                                                                .font: UIFont(name: "OpenSans-Regular", size: 13)!],
                                                               for: .normal)
    }

    var body: some View {
        VStack {

            ...

            Group {
                Spacer().frame(minHeight: 8, maxHeight: 30)
                Picker("video", selection: $selectorIndex) {
                    Text("Video On").tag(0)
                    Text("Video Off").tag(1)
                }
                .pickerStyle(SegmentedPickerStyle())
                .padding([.leading, .trailing], 16)

                Spacer().frame(minHeight: 8, maxHeight: 50)
                Button(action: { self.sendPressed() }) {
                    ZStack {
                        RoundedRectangle(cornerRadius: 100)
                        Text("go")
                            .font(.custom("Roboto-Bold", size: 36))
                            .foregroundColor(Color("MeetingGreen"))
                    }
                }
                .foregroundColor(Color("MeetingLightGreen").opacity(0.45))
                .frame(width: 137, height: 73)
            }
            Spacer()
        }
    }
}

Буду признателен за любые предложения!


person dandepeched    schedule 26.05.2020    source источник


Ответы (3)


Обновление: проблема, похоже, возникла из-за перекрытия View, потому что значение cornerRadius для RoundedRectangle было установлено на 100. Приведение значения cornerRadius к 55 восстановило бы функциональность Picker.

Проблема, похоже, вызвана RoundedRectangle(cornerRadius: 100) в ZStack. У меня нет объяснения, почему это происходит. Я добавлю причину, если когда-нибудь узнаю. Может быть ошибка SwiftUI. Я не могу сказать, пока не найду никаких связанных доказательств. Итак, вот код, который может заставить SegmentedControl работать без каких-либо проблем.

struct MeetingLogin: View {
    //...
    @State private var selectorIndex: Int = 0

    var body: some View {
        VStack {
            //...
            Group {
                Spacer().frame(minHeight: 8, maxHeight: 30)
                Picker("video", selection: $selectorIndex) {
                    Text("Video On").tag(0)
                    Text("Video Off").tag(1)
                }
                .pickerStyle(SegmentedPickerStyle())
                .padding([.leading, .trailing], 16)

                Spacer().frame(minHeight: 8, maxHeight: 50)
                Button(action: { self.sendPressed() }) {
                    ZStack {
                        RoundedRectangle(cornerRadius: 55)
                        Text("go")
                            .font(.custom("Roboto-Bold", size: 36))
                            .foregroundColor(Color("MeetingGreen"))
                    }
                }
                .foregroundColor(Color("MeetingLightGreen").opacity(0.45))
                .frame(width: 137, height: 73)
            }
            Spacer()
        }
    }
}
person Frankenstein    schedule 26.05.2020
comment
Вау, это действительно странно! Спасибо, что помогли! - person dandepeched; 26.05.2020
comment
@dandepeched Да, чувак, я тоже так думал. Я проголосовал за, так что этот пост привлекает внимание. - person Frankenstein; 26.05.2020
comment
Дальнейшее расследование показало, что проблема заключается в значении cornerRaduis. Когда он установлен на 50, Picker работает нормально, а также кнопка выглядит точно так же (из-за соотношения сторон кадра). Так что я верю, что это какая-то ошибка с перекрытием пользовательского интерфейса или чем-то подобным. Пожалуйста, добавьте эту информацию к своему ответу. - person dandepeched; 26.05.2020
comment
Да, касания регистрируются в RoundedRectangle. - person Frankenstein; 26.05.2020

В вашем коде / представлении отсутствует условие if, чтобы знать, что произойдет, когда selectorIndex равен 0 или 1.

Это должно выглядеть так:

var body: some View {

    VStack {
        if selectorIndex == 0 {
    //....Your VideoOn-View 
    } else {
    //Your VideoOff-View
    }
}
person Kuhlemann    schedule 26.05.2020
comment
Нет, SwiftUI Picker не требует условия «если» - person dandepeched; 26.05.2020
comment
Хьюлеманн предлагает использовать выбранный индекс средства выбора для условного отображения представления, когда выбран этот конкретный индекс. Он прав. Возможно, он мог бы включить действительный код средства выбора в свой пример, но его точка зрения верна, так зачем же его отрицать? - person Mozahler; 26.05.2020
comment
Его предложение не связано с этим конкретным вопросом. - person dandepeched; 27.05.2020

Xcode 12 iOS 14, вы можете получить его, добавив условие if-else в TapGesture вашего элемента управления сегментом (средства выбора)

@State private var profileSegmentIndex = 0
Picker(selection: self.$profileSegmentIndex, label: Text("Jamaica")) {
                    Text("My Posts").tag(0)
                
                Text("Favorites").tag(1)
            }
            .onTapGesture {
                if self.profileSegmentIndex == 0 {
                    self.profileSegmentIndex = 1
                } else {
                    self.profileSegmentIndex = 0
                }
            }
            .pickerStyle(SegmentedPickerStyle())
            .padding()

Если вам нужно использовать его с более чем двумя сегментами, вы можете попробовать с Enum :)

person Di Nerd    schedule 03.11.2020