Swift/UIKIt:如何使渐变背景占据 UITableView 的整个长度?

问题描述 投票:0回答:1

我有一个带有 UITableView 的应用程序。我们正在逐渐转换为 SwiftUI,因此 UITableView 基本上是 SwiftUI 视图的集合。我能够使用这两个函数让背景显示为渐变:

func createBackgroundGradient() -> CAGradientLayer {
    let gradientLayer = CAGradientLayer()
        
    gradientLayer.colors = [UIColor.red.cgColor, UIColor.white.cgColor, UIColor.red.cgColor]
    gradientLayer.locations = [0.0, 0.5, 1.0]
    gradientLayer.frame = self.tableView.bounds
        
    return gradientLayer
}

func refreshBackground() {
    tableView.backgroundView = nil
    let backgroundView = UIView()
    let gradientView = createBackgroundGradient()
    backgroundView.layer.addSublayer(gradientView)
    tableView.backgroundView = backgroundView
}

我从 viewWillLayoutSubview 调用这个函数,因为当我们从后端获取数据时,我会弹出视图。这用于设置屏幕长度的渐变。但是,我希望渐变占据整个 UITableView,并且希望它与表视图一起滚动(比屏幕的长度长得多),而不仅仅是坐在背景中,单元格在其上滚动.

这个问题的解决方案:UIScrollView的渐变背景色看起来像我想要的行为,但是当我将refreshBackround函数更改为这样时:

func refreshBackground() {
        if let gradientSublayer = self.gradientSublayer {
            gradientSublayer.removeFromSuperlayer()
        }
        self.gradientSublayer = createBackgroundGradient()
        tableView.layer.insertSublayer(self.gradientSublayer ?? createBackgroundGradient(), at: 0)
}

我没有看到任何行为差异 - 它仍然只是屏幕的长度,并且当我滚动时它不会改变位置。

有人知道解决这个问题的方法吗?我考虑过尝试用渐变的不同部分对不同部分进行着色,但这似乎会变得非常复杂,因为根据我们获取的数据,表中的各个部分可能存在也可能不存在后端(它可能看起来很糟糕,因为填充这些部分时渐变的部分会弹出)。

ios swift uitableview uikit
1个回答
0
投票

为了让

gradientLayer
完全占据
UITableView
。您需要订阅
tableView
的绑定更改,并且
refreshBackground
基于新的
bounds
。这是使用
Combine
的方法:

tableView.publisher(for: \.bounds)
    .removeDuplicates()
    .sink { [weak self] size in
        self?.createBackgroundGradient()
    }
    .store(in: &cancels)

var gradientLayer: CAGradientLayer!
func createBackgroundGradient() {
    if let gradientSublayer = self.gradientLayer {
        gradientSublayer.removeFromSuperlayer()
    }
    gradientLayer = CAGradientLayer()
        
    gradientLayer.colors = [UIColor.red.cgColor, UIColor.white.cgColor, UIColor.red.cgColor]
    gradientLayer.locations = [0.0, 0.5, 1.0]
    gradientLayer.zPosition = -1000
    gradientLayer.frame = self.collectionView.bounds
    tableView.layer.insertSublayer(self.gradientLayer, at: 0)
}
© www.soinside.com 2019 - 2024. All rights reserved.