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)
}