swift - 如何在 SwiftUI 中正确设置可调整的 Split View?

标签 swift resize swiftui drag splitview

这是我第一次尝试 SwiftUI,我正在尝试创建一个用作拆分 View 的 SwiftUI View ,在两个 View 的中心有一个可调节的 handle 。

这是我当前的代码实现示例:

struct ContentView: View {

    @State private var gestureTranslation = CGSize.zero
    @State private var prevTranslation = CGSize.zero

    var body: some View {

        VStack {
            Rectangle()
                .fill(Color.red)
                .frame(height: (UIScreen.main.bounds.height / 2) + self.gestureTranslation.height)
            RoundedRectangle(cornerRadius: 5)
            .frame(width: 40, height: 3)
            .foregroundColor(Color.gray)
            .padding(2)
            .gesture(DragGesture()
                    .onChanged({ value in
                        self.gestureTranslation = CGSize(width: value.translation.width + self.prevTranslation.width, height: value.translation.height + self.prevTranslation.height)

                    })
                    .onEnded({ value in
                        self.gestureTranslation = CGSize(width: value.translation.width + self.prevTranslation.width, height: value.translation.height + self.prevTranslation.height)

                        self.prevTranslation = self.gestureTranslation
                    })
            )
            Rectangle()
                .fill(Color.green)
                .frame(height: (UIScreen.main.bounds.height / 2) - self.gestureTranslation.height)
        }
    }
}

现在的样子:
[ split view screenshot[1]

这有点工作,但是在拖动 handle 时,它非常小故障,并且似乎需要大量拖动才能到达某个点。

请告诉我出了什么问题。谢谢你。

最佳答案

从我观察到的情况来看,问题似乎来自在拖动时重新定位的 handle 。为了抵消这一点,我在 handle 上设置了一个反向偏移,使其保持原位。我试图通过将其隐藏在其他 View (zIndex) 下方来尽可能地掩盖持久句柄位置。

我希望其他人对这个问题有更好的解决方案。 现在,这就是我所拥有的:

import PlaygroundSupport
import SwiftUI

struct SplitView<PrimaryView: View, SecondaryView: View>: View {

    // MARK: Props

    @GestureState private var offset: CGFloat = 0
    @State private var storedOffset: CGFloat = 0

    let primaryView: PrimaryView
    let secondaryView: SecondaryView


    // MARK: Initilization

    init(
        @ViewBuilder top: @escaping () -> PrimaryView,
        @ViewBuilder bottom: @escaping () -> SecondaryView)
    {
        self.primaryView = top()
        self.secondaryView = bottom()
    }


    // MARK: Body

    var body: some View {
        GeometryReader { proxy in
            VStack(spacing: 0) {
                self.primaryView
                    .frame(height: (proxy.size.height / 2) + self.totalOffset)
                    .zIndex(1)

                self.handle
                    .gesture(
                        DragGesture()
                            .updating(self.$offset, body: { value, state, _ in
                                state = value.translation.height
                            })
                            .onEnded { value in
                                self.storedOffset += value.translation.height
                            }
                    )
                    .offset(y: -self.offset)
                    .zIndex(0)

                self.secondaryView.zIndex(1)
            }
        }
    }


    // MARK: Computed Props

    var handle: some View {
        RoundedRectangle(cornerRadius: 5)
            .frame(width: 40, height: 3)
            .foregroundColor(Color.gray)
            .padding(2)
    }

    var totalOffset: CGFloat {
        storedOffset + offset
    }
}


// MARK: - Playground

let splitView = SplitView(top: {
    Rectangle().foregroundColor(.red)
}, bottom: {
    Rectangle().foregroundColor(.green)
})

PlaygroundPage.current.setLiveView(splitView)

只需将代码粘贴到 XCode Playground/Swift Playgrounds 中

如果您找到了改进我的代码的方法,请告诉我。

关于swift - 如何在 SwiftUI 中正确设置可调整的 Split View?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61169930/

相关文章:

ios - SKPaymentQueue.canMakePayments() 总是返回 true

qt - QGraphicsItem 交互式调整大小

firebase - SwiftUI 和 MVVM : How to display data from Firebase/Firestore in View?

swift - 如何在 SwiftUI 中为 ForEach 中的特定按钮设置动画?

ios - 在调用 API 之前从数组中移除对象

IOS 应用程序在后台不会显示推送通知。 swift

ios - 从 UICollectionViewController 中删除单元格的问题

java - 在 JPanel 中调整 JTextPane 的大小

javascript - 创建具有自动调整大小的文本区域

swiftui - 如何针对 Apple TV 定位 SwiftUI 应用程序