看起来SwiftUI正在获取/设置
frame
在图像视图的
transform
不是身份转换。从…起
frame
,
如果
使改变
属性不是身份转换,此属性的值未定义,因此应忽略。
对此属性的更改可以设置动画。但是,如果
使改变
属性包含非标识转换,frame属性的值未定义,不应修改。
当然,SwiftUI并不关心视图是否已转换,而是设置
框架
不管怎样,可能是为了根据SwiftUI自己的布局规则更新视图的框架。
包装
UIImageView
内部的另一个视图解决了这个问题。
class Wrapper: UIView {
let imageView: UIImageView
var image: UIImage? {
get { imageView.image }
set { imageView.image = newValue }
}
override init(frame: CGRect) {
imageView = UIImageView()
super.init(frame: frame)
addSubview(imageView)
imageView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
imageView.topAnchor.constraint(equalTo: topAnchor),
imageView.bottomAnchor.constraint(equalTo: bottomAnchor),
imageView.leftAnchor.constraint(equalTo: leftAnchor),
imageView.rightAnchor.constraint(equalTo: rightAnchor),
])
}
required init?(coder: NSCoder) {
fatalError()
}
}
struct UIImageViewRepresentable: UIViewRepresentable {
let image: UIImage?
func makeCoordinator() -> Coordinator {
Coordinator()
}
@MainActor
class Coordinator: NSObject {
@objc func handlePinchGesture(_ sender: UIPinchGestureRecognizer) {
guard let view = sender.view else { return }
let scaleResult = sender.view?.transform.scaledBy(x: sender.scale, y: sender.scale)
guard let scale = scaleResult, scale.a > 1, scale.d > 1 else { return }
sender.view?.transform = scale
sender.scale = 1
}
}
func makeUIView(context: Context) -> Wrapper {
let wrapper = Wrapper()
wrapper.image = image
wrapper.imageView.isUserInteractionEnabled = true
wrapper.imageView.addGestureRecognizer(UIPinchGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.handlePinchGesture(_:))))
return wrapper
}
func updateUIView(_ uiView: Wrapper, context: Context) {
uiView.image = image
}
}