如何将swiftui视图主体转换为uiimage在viewController中
我正在研究这种转换,并尝试了许多解决方案(扩展和方法),因为与此相关的问题和答案太多,但是没有什么能像我尝试过的解决方案那样帮助
尝试过的解决方案 <
< href =“ https://stackoverflow.com/a/64005395/15023395”> https://stackoverflow.com/a/a/64005395/15023395
a /41288197/1502395"> https://stackoverflow.com/a/a/41288197/15023395
extension View {
func asImage() -> UIImage {
let controller = UIHostingController(rootView: self)
// locate far out of screen
controller.view.frame = CGRect(x: 0, y: CGFloat(Int.max), width: 1, height: 1)
UIApplication.shared.windows.first!.rootViewController?.view.addSubview(controller.view)
let size = controller.sizeThatFits(in: UIScreen.main.bounds.size)
controller.view.bounds = CGRect(origin: .zero, size: size)
controller.view.sizeToFit()
let image = controller.view.asImage()
controller.view.removeFromSuperview()
return image
}
}
extension UIView {
func asImage() -> UIImage {
let renderer = UIGraphicsImageRenderer(bounds: bounds)
return renderer.image { rendererContext in
// [!!] Uncomment to clip resulting image
// rendererContext.cgContext.addPath(
// UIBezierPath(roundedRect: bounds, cornerRadius: 20).cgPath)
// rendererContext.cgContext.clip()
// As commented by @MaxIsom below in some cases might be needed
// to make this asynchronously, so uncomment below DispatchQueue
// if you'd same met crash
// DispatchQueue.main.async {
layer.render(in: rendererContext.cgContext)
// }
}
}
}
此解决方案有所帮助,但我不想将image添加为Supperiew 的子视图
func extractView(){
let hostView = UIHostingController(rootView: ContentView())
hostView.view.translatesAutoresizingMaskIntoConstraints = false
let constraints = [
hostView.view.topAnchor.constraint(equalTo: view.topAnchor),
hostView.view.bottomAnchor.constraint(equalTo: view.bottomAnchor),
hostView.view.leadingAnchor.constraint(equalTo: view.leadingAnchor),
hostView.view.trailingAnchor.constraint(equalTo: view.trailingAnchor),
hostView.view.widthAnchor.constraint(equalTo: view.widthAnchor),
hostView.view.heightAnchor.constraint(equalTo: view.heightAnchor),
]
self.view.addSubview(hostView.view)
self.view.addConstraints(constraints)
}
我想做什么? Strong>
我有一个扩展SwiftUi视图的结构,并且我的设计中有一个设计。现在,我想将SwiftUi视图转换为故事板的ViewController内部的UIImage,当我的屏幕加载并 viewDidload()
函数调用时,System UiimageView在故事板中的映像
这是我的SwiftUi代码< /strong>
import SwiftUI
struct ContentView: View {
var body: some View {
ZStack(alignment: .center){
Rectangle()
.frame(width: 200, height: 75)
.cornerRadius(10)
.foregroundColor(.white)
Circle()
.stroke(lineWidth:5)
.foregroundColor(.red)
.frame(width: 75, height: 75, alignment: .leading)
.background(
Image("tempimage")
.resizable()
)
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您 can 执行此操作...但不是
viewDidload()
- 您必须至少等到view> viewdidlayoutsubviews()
。而且,必须将视图添加到视图层次结构中 - 但是一旦我们生成图像,就可以将其删除,以使其从未看到“屏幕上”。
注意:此处的所有“结果”图像使用:
240 x 200
图像视图.contentMode = .center
,并给出
> uiimage
从swiftuicontentView
一个黄色背景生成,因为我们需要解决一些布局怪癖。因此,要生成图像并将其设置为
uiimageView
,我们可以做到这一点:使用此
image> image fromContentView()
func:结果#1:
请注意顶部的20点黄色带,并且内容不垂直居中...这是因为
uihostingController
应用了安全区域布局指南。夫妇可以解决这个问题...
如果我们添加此行:
我们得到此结果:
渲染图像现在具有20个点顶和底部的“安全区域”插图。
如果我们不想要任何安全区域插图,我们可以使用此扩展名:
并将其在我们的Func中的第一行更改为:
我们得到此结果:
SwiftUi
contentView
布局使用ZSTACK
,其中其内容(“ ring”)超过其垂直边界,戒指的顶部和底部被“夹住”。我们可以通过更改
contentView
中的框架来解决这个问题:或通过增加加载视图的帧高度,例如:
这是一个完整的实现(使用未修改的
contentview
):You can do this... but not in
viewDidLoad()
-- you have to wait at least untilviewDidLayoutSubviews()
.And, the view must be added to the view hierarchy -- but it can be removed as soon as we generate the image so it's never seen "on-screen."
Note: all "result" images here use:
240 x 200
image view.contentMode = .center
and we give the
UIImage
generate from the SwiftUIContentView
a yellow background, because we will need to address some layout quirks.So, to generate the image and set it to a
UIImageView
, we can do this:using this
imageFromContentView()
func:Result #1:
Notice the 20-pt yellow band at the top, and the content is not vertically centered... that's because the
UIHostingController
applies a safe area layout guide.Couple options to get around that...
If we add this line:
we get this result:
the rendered image now has 20-pts Top and Bottom "safe area" insets.
If we don't want any safe area insets, we can use this extension:
and change the first line in our func to:
and we get this result:
Because the SwiftUI
ContentView
layout is using azStack
where its content (the "ring") exceeds its vertical bounds, the top and bottom of the ring is "clipped."We can fix that either by changing the framing in
ContentView
:or by increasing the frame height of the loaded view, like this for example:
Here's a complete implementation (using your unmodified
ContentView
):