【问题标题】:SwiftUI view is adjusting itself near the safe areaSwiftUI 视图在安全区域附近自行调整
【发布时间】:2021-11-20 19:56:06
【问题描述】:

我在将包含 SwiftUI 视图的视图移动到屏幕边缘附近时遇到问题。 SwiftUI 视图会自行移动以避免被安全区域插图阻挡

我正在使用 UIKit 来处理通过UIHostingControllerUIPanGestureRecognizer 拖动视图。这是代码

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 视图是否需要该修饰符!你为什么需要它?我会删除它!

标签: ios swift swiftui uikit


【解决方案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
        })

    }
}

【讨论】:

    猜你喜欢
    • 2022-08-19
    • 2020-06-25
    • 2018-04-03
    • 2021-10-06
    • 2020-08-16
    • 2019-11-28
    • 1970-01-01
    • 2019-10-17
    • 1970-01-01
    相关资源
    最近更新 更多