如何正确制作此 Picker 剪辑

Posted

技术标签:

【中文标题】如何正确制作此 Picker 剪辑【英文标题】:How do I make this Picker clip properly 【发布时间】:2020-08-20 02:55:49 【问题描述】:

我通过调用下面的视图在 HStack 中创建一组并排选择器。每个选择器的“控制”区域在选择器左侧比应有的要宽得多。 “.clipped()” 应该解决这个问题,但它不起作用。在我开发代码的某个时候,它可以工作,但现在我无法取回它。当我尝试操纵选择器时,我可以将最右边的选择器移动到右侧 3 列的任意位置。左列根本无法操作。这是怎么回事?

struct SinglePickerView: View 
    @Binding var note: Int
    let notes: [String]
    let width: CGFloat
   
    var body: some View 
        VStack 
            ZStack (alignment: .center) 
                RoundedRectangle(cornerRadius: 5)
                    .fill(Color(red: 192, green: 192, blue: 192))
                    .frame(width: width-10, height: 25)
                Text("\(notes[note])")
                .foregroundColor(.black)
            

            Picker(selection: $note, label: Text("")) 
                ForEach(0 ..< 72)  index in
                    Text("\(self.notes[index])")
                        .foregroundColor(.white)
                        .tag(index)
               
            
            .labelsHidden()
            .frame(width: width)
            .clipped()
        
    

【问题讨论】:

【参考方案1】:

尝试在父容器处移动剪辑,如下所示。使用 Xcode 12 / ios 14 测试。

struct SinglePickerView: View 
    @Binding var note: Int
    let notes: [String]
    let width: CGFloat

    var body: some View 
        VStack 
            ZStack (alignment: .center) 
                RoundedRectangle(cornerRadius: 5)
                    .fill(Color(red: 192, green: 192, blue: 192))
                    .frame(width: width-10, height: 25)
                Text("\(notes[note])")
                .foregroundColor(.black)
            

            Picker(selection: $note, label: Text("")) 
                ForEach(0 ..< notes.count, id: \.self)  index in
                    Text("\(self.notes[index])")
                        .foregroundColor(.white)
                        .tag(index)
               
            
            .labelsHidden()
        
        .frame(width: width)
        .contentShape(Rectangle())
        .clipped()
    


struct TestStackOfPickers: View 
    let notes = (1...10).map  String($0) 
    @State var note1 = 1
    @State var note2 = 5
    @State var note3 = 3

    var body: some View 
        HStack 
            SinglePickerView(note: $note1, notes: notes, width: 80).border(Color.red)
            SinglePickerView(note: $note2, notes: notes, width: 80).border(Color.red)
            SinglePickerView(note: $note3, notes: notes, width: 80).border(Color.red)
        
    

【讨论】:

似乎没有帮助。我在 iOS 13.6 和 XCode 11.6 上。我尝试按照您的建议将 .clipped() 移到 VStack 中,并在任一位置添加 .contentShape() 。我确实看到,在视图预览中,当它停止时,选择器周围会出现蓝框,正是我希望看到它们的位置。【参考方案2】:

我终于找到了真正答案的参考。下面的公式至少在 iOS 13.6 和 XCode 11.6 中有效。

Picker(selection: $note, label: Text("")) 
    ForEach(0 ..< 72)  index in
        Text("\(self.notes[index])")
            .frame(width: self.width)
            .foregroundColor(.white)
            .tag(index)
       

.labelsHidden()
.frame(width: width)
.compositingGroup() 
.clipped()

【讨论】:

以上是关于如何正确制作此 Picker 剪辑的主要内容,如果未能解决你的问题,请参考以下文章

如何正确将 16Bit 字节数组转换为音频剪辑数据?

如何剪辑和转换图像,添加圆角和透视?

如何在将 UIView 制作成图像之前正确布局

影片剪辑未显示正确的帧

当引用为 css 剪辑路径属性时,SVG 剪辑路径的位置不正确

子视图未正确定位