SwiftUI-隐藏ScrollView的指示器使其停止滚动

时间:2019-11-30 14:28:16

标签: swift macos swiftui

我正在尝试隐藏ScrollView的指示器,但是当我尝试隐藏ScrollView时,它不再滚动。如果需要的话,我正在使用macOS。

ScrollView(showsIndicators: false) {
    // Everything is in here
}

3 个答案:

答案 0 :(得分:1)

应@SoOverIt的要求

演示:

demo

没什么特别的,只是启动了其他一些测试示例。 Xcode 11.2 / macOS 10.15

var body : some View {

    VStack {
        ScrollView([.vertical], showsIndicators: false) {
            Group {
            Text("AAA")
            Text("BBB")
            Text("CCC")
            Text("DDD")
            Text("EEE")
            }
            Group {
            Text("AAA")
            Text("BBB")
            Text("CCC")
            Text("DDD")
            Text("EEE")
            }
            Group {
            Text("AAA")
            Text("BBB")
            Text("CCC")
            Text("DDD")
            Text("EEE")
            }
            Group {
            Text("AAA")
            Text("BBB")
            Text("CCC")
            Text("DDD")
            Text("EEE")
            }
        }
        .frame(height: 100)
        .border(Color.blue)
    }
    .border(Color.red)
}

答案 1 :(得分:0)

我解决了这个问题。

extension View {
    func hideIndicators() -> some View {
        return PanelScrollView{ self }
    }
}

struct PanelScrollView<Content> : View where Content : View {
    let content: () -> Content

    var body: some View {
        PanelScrollViewControllerRepresentable(content: self.content())
    }
}

struct PanelScrollViewControllerRepresentable<Content>: NSViewControllerRepresentable where Content: View{
    func makeNSViewController(context: Context) -> PanelScrollViewHostingController<Content> {
        return PanelScrollViewHostingController(rootView: self.content)
    }

    func updateNSViewController(_ nsViewController: PanelScrollViewHostingController<Content>, context: Context) {
    }

    typealias NSViewControllerType = PanelScrollViewHostingController<Content>

    let content: Content


}

class PanelScrollViewHostingController<Content>: NSHostingController<Content> where Content : View {

    var scrollView: NSScrollView?

    override func viewDidAppear() {
        self.scrollView = findNSScrollView(view: self.view)
        self.scrollView?.scrollerStyle = .overlay
        self.scrollView?.hasVerticalScroller = false
        self.scrollView?.hasHorizontalScroller = false
        super.viewDidAppear()
    }

    func findNSScrollView(view: NSView?) -> NSScrollView? {
        if view?.isKind(of: NSScrollView.self) ?? false {
            return (view as? NSScrollView)
        }

        for v in view?.subviews ?? [] {
            if let vc = findNSScrollView(view: v) {
                return vc
            }
        }

        return nil
    }
}

预览:

struct MyScrollView_Previews: PreviewProvider {
    static var previews: some View {
        ScrollView{
            VStack{
                Text("hello")
                Text("hello")
                Text("hello")
                Text("hello")
                Text("hello")
            }
        }.hideIndicators()
    }
}

答案 2 :(得分:0)

所以...我认为这是目前的唯一方法。

您基本上只需将View放在指标ScrollView上,并将backgroundColor与背景View

注意:这显然仅在您的背景是静态的且尾端无内容的情况下有效。

想法

struct ContentView: View {
    
    @Environment(\.colorScheme) var colorScheme: ColorScheme
    
    let yourBackgroundColorLight: Color = .white
    let yourBackgroundColorDark: Color = .black

    var yourBackgroundColor: Color { colorScheme == .light ? yourBackgroundColorLight : yourBackgroundColorDark }
    
    
    var body: some View {
        ScrollView {
            VStack {
                ForEach(0..<1000) { i in
                    Text(String(i)).frame(width: 280).foregroundColor(.green)
                }
            }
        }
        .background(yourBackgroundColor) //<-- Same
        .overlay(
            HStack {
                Spacer()
                Rectangle()
                    .frame(width: 10)
                    .foregroundColor(yourBackgroundColor) //<-- Same
            }
        )
    }
}

紧凑版

您可以这样改善,我想您可以在资产内部动态设置颜色。

用法:

ScrollView {
    ...
}
.hideIndicators(with: <#Your Color#>)

实施:

extension View {
    func hideIndicators(with color: Color) -> some View {
        return modifier(HideIndicators(color: color))
    }
}


struct HideIndicators: ViewModifier {
    let color: Color
    
    func body(content: Content) -> some View {
        content
            .overlay(
                HStack {
                    Spacer()
                    Rectangle()
                        .frame(width: 10)
                        .foregroundColor(color)
                }
            )
    }
}