SwiftUI 视图在安全区域附近自行调整
Posted
技术标签:
【中文标题】SwiftUI 视图在安全区域附近自行调整【英文标题】:SwiftUI view is adjusting itself near the safe area 【发布时间】:2021-11-20 19:56:06 【问题描述】:我在将包含 SwiftUI 视图的视图移动到屏幕边缘附近时遇到问题。 SwiftUI 视图会自行移动以避免被安全区域插图阻挡
我正在使用 UIKit 来处理通过UIHostingController
和UIPanGestureRecognizer
拖动视图。这是代码
import UIKit
class ViewController: UIViewController
var contentView: UIView!
override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view.
let contentVc = UIHostingController(rootView: Content())
addChild(contentVc)
contentView = contentVc.view
let contentHeight = contentView.sizeThatFits(view.bounds.size).height
contentView.frame = CGRect(x: 0, y: 200, width: view.bounds.width, height: contentHeight)
view.addSubview(contentView)
contentVc.didMove(toParent: self)
let drag = UIPanGestureRecognizer(target: self, action: #selector(drag(_:)))
contentView.addGestureRecognizer(drag)
view.backgroundColor = .orange
var startingPoint = CGPoint.zero
@objc func drag(_ gesture: UIPanGestureRecognizer)
switch gesture.state
case .began:
startingPoint = contentView.frame.origin
case .changed:
let location = gesture.translation(in: view)
contentView.frame.origin.y = startingPoint.y + location.y
default:
break
import SwiftUI
struct Content: View
var body: some View
VStack
ForEach(0..<10) i in
Text(String(i))
.background(Color.blue)
.padding(.vertical, 32)
.ignoresSafeArea()
我期望的是蓝色视图不会垂直调整自身(在预览中,蓝色视图的顶部填充正在缩小)
【问题讨论】:
你总是在期待从一开始就没有的东西。当视图命中 safeArea 时,该修饰符会修改视图。 @swiftPunk 好的,这就解释了为什么当我将视图拖到 safeArea 时,蓝色会延伸 bc,因为它忽略了安全区域。我理解的对吗? 没错。 @ErickES7 好的,所以 ignoreSafeArea 不是用来解决这个问题的修饰符。我的标题不包括 ignoresSafeArea 不工作 我不确定您的 SwiftUI 视图是否需要该修饰符!你为什么需要它?我会删除它! 【参考方案1】:我找到了两种解决此问题的方法:
方式一:使用 UIKit 手势!
class ViewController: UIViewController
var contentView: UIView!
override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view.
let contentVc = UIHostingController(rootView: Content())
addChild(contentVc)
contentView = contentVc.view
let contentHeight = contentView.sizeThatFits(view.bounds.size).height
contentView.frame = CGRect(x: 0, y: 100, width: view.bounds.width, height: contentHeight)
contentView.backgroundColor = .clear
view.addSubview(contentView)
contentVc.didMove(toParent: self)
let drag = UIPanGestureRecognizer(target: self, action: #selector(drag(_:)))
contentView.addGestureRecognizer(drag)
view.backgroundColor = .orange
var startingPoint = CGPoint.zero
@objc func drag(_ gesture: UIPanGestureRecognizer)
switch gesture.state
case .began:
startingPoint = contentView.frame.origin
case .changed:
let location = gesture.translation(in: view)
contentView.frame.origin.y = startingPoint.y + location.y
default:
break
import SwiftUI
struct Content: View
var body: some View
VStack
ForEach(0..<10) i in
Text(String(i))
.padding()
.background(Color.blue)
.frame(maxWidth: .infinity)
.background(Color.white)
方式二:使用 SwiftUI 手势!
class ViewController: UIViewController
var contentView: UIView!
override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view.
let contentVc = UIHostingController(rootView: Content())
addChild(contentVc)
contentView = contentVc.view
contentView.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height)
contentView.backgroundColor = .clear
view.addSubview(contentView)
contentVc.didMove(toParent: self)
view.backgroundColor = .orange
struct Content: View
@State private var offset: CGFloat = .zero
@State private var lastOffset: CGFloat = .zero
var body: some View
VStack
ForEach(0..<10) i in
Text(String(i))
.padding()
.background(Color.blue)
.frame(maxWidth: .infinity)
.background(Color.white)
.offset(y: offset)
.gesture(DragGesture(minimumDistance: .zero, coordinateSpace: .local).onChanged value in
offset = lastOffset + value.translation.height
.onEnded value in
lastOffset = lastOffset + value.translation.height
offset = lastOffset
)
【讨论】:
以上是关于SwiftUI 视图在安全区域附近自行调整的主要内容,如果未能解决你的问题,请参考以下文章
如何使 AVFoundation 预览视图占据 SwiftUI 中的所有屏幕,而不考虑安全区域?
如何使 SwiftUI 列表行背景颜色扩展整个宽度,包括安全区域之外