SwiftUI高级用法

SwiftUI高级用法
1.frame布局
2. postion 控件偏移
3.layoutPrority 布局优先级
4 GeometryReader读取上层视图提供的文件大小
5 preference,anchorPreference 从里向外传值
6 aligentguid 自定义对其方式,不同父布局子控件实现对齐
目前就这么多,下一篇写一下 combing 相关,最近项目也比较忙,用swiftui实战开发,还是有不少坑要踏过去的

struct AligmnetDemo:View{
    @State var textSize:CGSize = .zero
    
    
    @State var anchorTextSize:CGSize = .zero
    var body: some View{
        GeometryReader { mProxy in

        HStack(alignment:.myaligent){
            
            Circle()
                .fixedSize()
                .frame(width: 12, height: 12, alignment: .center)
                .alignmentGuide(.myaligent) { dim in
                    dim[VerticalAlignment.center]
                }
            VStack(alignment:.center){
                GeometryReader { proxy in
                    //获取它的尺寸,通过背景来拿,然后显示在白色
                    Text(proxy.size.debugDescription)
                        .background(
                            GeometryReader(content: { prox in
                                Color.gray
                                    .preference(key: MyPrefernenceKey.self, value: prox.size)
                            })
                            
                        )
                        
                    
                }.frame(width: 200, height: 30, alignment: .center)
                    .background(Color.purple)
                 
                //position 相对当前容器所在父容器的相对坐标
                //layoutPriority 布局优先级和maxwidth,maxheight相关
                //.anchorPreference 传递的数据显示
                Text(String(describing: self.anchorTextSize)).position(x: 80, y: 10).frame(maxHeight:100).layoutPriority(1).background(Color.yellow)
                    
                
                //.anchorPreference 传递数据
                Text("cdef").frame(maxHeight:200).layoutPriority(0)
                    .background(GeometryReader(content: { proxx in
                        Color.green
                            .anchorPreference(key: MyAnchorPrefernenceKey.self, value: .bounds) { anchor in
                                MyAnchorPrefernenceKey.MyAnchorData(anchor: anchor)
                            }
                    }))
                //红色圆点点和它对齐 aligentGuid
                //显示灰色视图尺寸,geometryReader获取背景尺寸,然后preference将值传出来,从里向外传递信息机制
                Text(String(describing: textSize)).frame(maxHeight:200).layoutPriority(0).background(Color.white).fixedSize(horizontal: false, vertical: true).alignmentGuide(.myaligent) { dim in
                    dim[VerticalAlignment.center]
                }
                /*
                 idealwidth,idealheight 理想布局,只有在fixsize的水平或垂直方向设置true才会生效
                 */
                Text("测试IdealWidth的数据会适配fixedSize的水平和垂直")
                    .frame(idealWidth:60)
                    .foregroundColor(Color.white)
                    .fixedSize(horizontal: true, vertical: false)
                    
            }.background(Color.black)
        }.background(Color.purple)
            .onPreferenceChange(MyPrefernenceKey.self) { size in
                self.textSize = size
            }
            .onPreferenceChange(MyAnchorPrefernenceKey.self) { data in
                
                self.anchorTextSize = mProxy[data.anchor!].size
            }
            
        }
    }
}
//
struct MyPrefernenceKey:PreferenceKey{
    /// The type of value produced by this preference.
    typealias Value = CGSize

    /// The default value of the preference.
    ///
    /// Views that have no explicit value for the key produce this default
    /// value. Combining child views may remove an implicit value produced by
    /// using the default. This means that `reduce(value: &x, nextValue:
    /// {defaultValue})` shouldn't change the meaning of `x`.
    static var defaultValue: Self.Value  = .zero

    /// Combines a sequence of values by modifying the previously-accumulated
    /// value with the result of a closure that provides the next value.
    ///
    /// This method receives its values in view-tree order. Conceptually, this
    /// combines the preference value from one tree with that of its next
    /// sibling.
    ///
    /// - Parameters:
    ///   - value: The value accumulated through previous calls to this method.
    ///     The implementation should modify this value.
    ///   - nextValue: A closure that returns the next value in the sequence.
    static func reduce(value: inout Self.Value, nextValue: () -> Self.Value){
        value = nextValue()
    }
    
}
//
struct MyAnchorPrefernenceKey:PreferenceKey{
    /// The type of value produced by this preference.
    typealias Value = MyAnchorData

    /// The default value of the preference.
    ///
    /// Views that have no explicit value for the key produce this default
    /// value. Combining child views may remove an implicit value produced by
    /// using the default. This means that `reduce(value: &x, nextValue:
    /// {defaultValue})` shouldn't change the meaning of `x`.
    static var defaultValue: Self.Value  = MyAnchorData()

    /// Combines a sequence of values by modifying the previously-accumulated
    /// value with the result of a closure that provides the next value.
    ///
    /// This method receives its values in view-tree order. Conceptually, this
    /// combines the preference value from one tree with that of its next
    /// sibling.
    ///
    /// - Parameters:
    ///   - value: The value accumulated through previous calls to this method.
    ///     The implementation should modify this value.
    ///   - nextValue: A closure that returns the next value in the sequence.
    static func reduce(value: inout Self.Value, nextValue: () -> Self.Value){
        value.anchor = nextValue().anchor ?? value.anchor
    }
    
    struct MyAnchorData:Equatable{
        var anchor:Anchor<CGRect>? = nil
        static func == (lhs:Self,rhs:Self)->Bool{
            return false
        }
    }
    
}




struct MyAligent:AlignmentID{
    static func defaultValue(in context: ViewDimensions) -> CGFloat{
        return context[VerticalAlignment.center]
    }
}
extension VerticalAlignment{
    static let myaligent = VerticalAlignment(MyAligent.self)
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值