Swift UIViewRepresentable及其内容';s固有尺寸
我为Swift UIViewRepresentable及其内容';s固有尺寸,swift,autolayout,swiftui,Swift,Autolayout,Swiftui,我为UIVisualEffectView创建了一个UIViewRepresentable,以使某些组件充满活力。这是可行的,但它似乎有时会垂直收缩控件,或者只是在运行时随机改变控件的边界。我似乎无法使它可靠地工作。我需要它来处理任何SwiftUI内容,甚至是其他用来代替内容的UIViewRepresentable。将UIVisualEffectView包装在UIView中并使用自动布局似乎有帮助,但其他控件(如包装在uiviewrepresentable中的自定义UILabel会被垂直剪裁) 当
UIVisualEffectView
创建了一个UIViewRepresentable
,以使某些组件充满活力。这是可行的,但它似乎有时会垂直收缩控件,或者只是在运行时随机改变控件的边界。我似乎无法使它可靠地工作。我需要它来处理任何SwiftUI内容,甚至是其他用来代替内容的UIViewRepresentable
。将UIVisualEffectView
包装在UIView
中并使用自动布局似乎有帮助,但其他控件(如包装在uiviewrepresentable
中的自定义UILabel
会被垂直剪裁)
当在设备上运行时,在VStack
的内部有其他视图,您将看到部分从底部剪裁的“Hello”。在预览中,您将看到“Hello”周围有一个大得多的蓝色矩形(边界),而我希望这是一个拥抱内容的矩形。VStack
不假定整个视图的完整自然高度
使用fixedSize()
不起作用,与其他控件一起使用时会产生更奇怪的结果。为什么这么复杂
试试这个:
struct Blur: UIViewRepresentable {
#if os(iOS)
var style: UIBlurEffect.Style = .systemMaterial
#else
var style: UIBlurEffect.Style = .light
#endif
init(_ style: UIBlurEffect.Style = .dark) {
self.style = style
}
func makeUIView(context: Context) -> UIVisualEffectView {
return UIVisualEffectView(effect: UIBlurEffect(style: style))
}
func updateUIView(_ uiView: UIVisualEffectView, context: Context) {
uiView.effect = UIBlurEffect(style: style)
}
}
和使用:
Text("Great text with prominent")
.font(.largeTitle)
.padding()
.background(Blur(.prominent))
通常,您不应该在UIViewRepresentable->中使用约束,大小将由父视图定义,如本例中的文本或VStack,后者为模糊提供正确的大小。通常情况下,模糊不是孤立的,但典型的是模糊的背景,因为你想在其上放置文本,以便更好地阅读文本。为什么这么复杂
试试这个:
struct Blur: UIViewRepresentable {
#if os(iOS)
var style: UIBlurEffect.Style = .systemMaterial
#else
var style: UIBlurEffect.Style = .light
#endif
init(_ style: UIBlurEffect.Style = .dark) {
self.style = style
}
func makeUIView(context: Context) -> UIVisualEffectView {
return UIVisualEffectView(effect: UIBlurEffect(style: style))
}
func updateUIView(_ uiView: UIVisualEffectView, context: Context) {
uiView.effect = UIBlurEffect(style: style)
}
}
和使用:
Text("Great text with prominent")
.font(.largeTitle)
.padding()
.background(Blur(.prominent))
通常,您不应该在UIViewRepresentable->中使用约束,大小将由父视图定义,如本例中的文本或VStack,后者为模糊提供正确的大小。通常情况下,模糊不是孤立的,但典型的是模糊的背景,因为您希望在其上放置文本,以便更好地阅读文本。尝试了各种技术和技巧后,我根本无法让UIKit容器(即
VibrantView
)可靠地容纳其快速UI内容,没有在顶部添加固定大小的.frame(…)
修改器-这使得它很难与动态大小的文本一起使用
对我有效的是一点小技巧,可能不适用于所有的通用视图(也可能不适用于几十个视图),但适用于简单的用例,特别是如果您在动态大小的UITableViewCell
中托管它
想法是使用同一视图的虚拟版本,并在.overlay(…)
中设置VibrantView
。这将强制覆盖采用与父SwitUI视图相同的总体大小。由于要应用的视图修改器是与VibrantView
包装的视图相同的视图的副本,因此在运行时和Xcode预览中,最终会得到正确的动态大小
比如说:
SomeView()
.frame(minWidth: 0, maxWidth: .infinity)
.overlay(
VibrantView(vibrancyBlurEffectStyle: .dark) {
SomeView()
.frame(minWidth: 0, maxWidth: .infinity)
}
)
Circle()
.foregroundColor(.clear)
.frame(width: 33, height: 33)
.overlay(
VibrantView(vibrancyBlurEffectStyle: .systemMaterialDark) {
Image("some image")
.resizable()
}
)
我可以想象将其转换为一个修饰符,以便在一个调用中封装上述内容,但在我的情况下,为了确保它对图像保持性能,我正在做如下操作:
SomeView()
.frame(minWidth: 0, maxWidth: .infinity)
.overlay(
VibrantView(vibrancyBlurEffectStyle: .dark) {
SomeView()
.frame(minWidth: 0, maxWidth: .infinity)
}
)
Circle()
.foregroundColor(.clear)
.frame(width: 33, height: 33)
.overlay(
VibrantView(vibrancyBlurEffectStyle: .systemMaterialDark) {
Image("some image")
.resizable()
}
)
创建一个圆
可以说比实际图像更轻。我创建了一个透明的圆圈,在那里设置了图像的实际大小,然后将VibrantView
容器放入overlay
中,在尝试了各种技术和技巧之后-我根本无法让UIKit容器(即VibrantView
)可靠地容纳其SwiftUI内容,没有在顶部添加固定大小的.frame(…)
修改器-这使得它很难与动态大小的文本一起使用
对我有效的是一点小技巧,可能不适用于所有的通用视图(也可能不适用于几十个视图),但适用于简单的用例,特别是如果您在动态大小的UITableViewCell
中托管它
想法是使用同一视图的虚拟版本,并在.overlay(…)
中设置VibrantView
。这将强制覆盖采用与父SwitUI视图相同的总体大小。由于要应用的视图修改器是与VibrantView
包装的视图相同的视图的副本,因此在运行时和Xcode预览中,最终会得到正确的动态大小
比如说:
SomeView()
.frame(minWidth: 0, maxWidth: .infinity)
.overlay(
VibrantView(vibrancyBlurEffectStyle: .dark) {
SomeView()
.frame(minWidth: 0, maxWidth: .infinity)
}
)
Circle()
.foregroundColor(.clear)
.frame(width: 33, height: 33)
.overlay(
VibrantView(vibrancyBlurEffectStyle: .systemMaterialDark) {
Image("some image")
.resizable()
}
)
我可以想象将其转换为一个修饰符,以便在一个调用中封装上述内容,但在我的情况下,为了确保它对图像保持性能,我正在做如下操作:
SomeView()
.frame(minWidth: 0, maxWidth: .infinity)
.overlay(
VibrantView(vibrancyBlurEffectStyle: .dark) {
SomeView()
.frame(minWidth: 0, maxWidth: .infinity)
}
)
Circle()
.foregroundColor(.clear)
.frame(width: 33, height: 33)
.overlay(
VibrantView(vibrancyBlurEffectStyle: .systemMaterialDark) {
Image("some image")
.resizable()
}
)
创建一个圆
可以说比实际图像更轻。我创建一个透明的圆圈,在那里设置图像的实际大小,然后将VibrantView
容器放入覆盖层
如果你看我的代码-我没有使用模糊,我使用的是vibrance。对于Vibrance,我需要将内容视图添加到vibrantUIVisualEffectView
的contentView
。我不是把它用作背景,我是把它用作容器,所以你的技术不起作用。你说得对……这个怎么样。刚刚尝试过-同样的问题,而且我现在看到一个编译错误,关于@objc layoutSubviews不受泛型类支持_(ツ)_/“如果你看我的代码-我没有使用模糊,我使用的是Vibrance。对于Vibrance,我需要将内容视图添加到vibrantUIVisualEffectView
的contentView
中。我没有将其用作背景,而是将其用作容器,因此你的技术不起作用。你是对的……这是怎么回事。只是尝试了一下-相同。”此外,我现在看到一个编译错误,它与泛型类不支持的@objc layoutSubviews有关_(ツ)_/为什么否决?答案没有帮助,也不适用于我需要使用ViewBuilder
fo的情况