当前位置: 首页 > 知识库问答 >
问题:

UIPickerView确实通过了行

唐兴贤
2023-03-14

我有一个演示应用程序:

正如你所看到的,背景的alpha正在根据值变为黑色。

但问题是没有平稳过渡:

从GIF中可以看到,只有滚动结束后,背景才会发生变化。我不想让事情变成那样。

这是我的代码:

class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

    @IBOutlet weak var pickerView: UIPickerView!
    @IBOutlet weak var backView: UIView!
    
    let max = 100
    
    override func viewDidLoad() {
        super.viewDidLoad()

        pickerView.delegate = self
        pickerView.dataSource = self
    }
    
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }
    
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return max + 1 // To include '0'
    }
    
    func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
        
        let l = UILabel(frame: .zero)
        l.text = String(max - row)
        l.textColor = .white
        
        l.font = UIFont.preferredFont(forTextStyle: .title3)
        l.textAlignment = .center
        
        return l
    }
    
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        backView.alpha = CGFloat(max - row) / 100
    }


}

我给出了委托uiview而不是String,因为我有一个想法:每次每一行的位置发生变化时都要进行测试,当一行位于屏幕中间时,我应该更新背景。但不幸的是我不知道怎么做。

也许你能帮忙?或者提出其他的想法?

谢谢!

共有1个答案

梁俊智
2023-03-14

委托方法DidSelectRow仅在滚动停止时调用,因此这不是您应该更新alpha的地方。UIPickerView没有将在滚动期间通知您更改的委托方法,但是UIPickerView将调用您的数据源和委托方法来获取给定行的标题或视图,以便在用户滚动时显示。所以你应该做的就是把你的alpa变化逻辑移到那里:

func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
    backView.alpha = CGFloat(max - row) / 100
}

请注意,在加载UIPickerView时将调用此委托方法,因此可能您应该禁用alpha更改,直到视图没有正确地布局出来(可能ViewDidInceure会这样做)。

由于delegate方法有时会发生意外的行为(不仅调用下一行,还调用选取器中的任何一行),我们应该存储并检查该行是比上次保存的值早一步还是晚一步,否则我们应该忽略这一点。我做了一个简单的演示来演示它是如何工作的:

import UIKit

class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
    private let pickerView = UIPickerView()
    private var isPickerReady = false
    private var lastValue = 0
    private let max = 100

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(pickerView)
        pickerView.translatesAutoresizingMaskIntoConstraints = false

        pickerView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        pickerView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
        pickerView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        pickerView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true


        pickerView.delegate = self
        pickerView.dataSource = self
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        isPickerReady = true
    }

    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return max
    }

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        // Do not update the value until the view is not loaded 
        // Only consider delegate methods which are one step ahead or behind the last value
        if row + 1 == lastValue && isPickerReady || row - 1 == lastValue && isPickerReady {
            lastValue = row
            view.alpha = CGFloat(max - lastValue ) / 100
        }
        return "Tiltle \(row)"
    }
}
 类似资料:
  • 本文向大家介绍通过实例了解java TransferQueue,包括了通过实例了解java TransferQueue的使用技巧和注意事项,需要的朋友参考一下 序言 本文主要简介一下TransferQueue。 TransferQueue TransferQueue(java7引入)继承了BlockingQueue(BlockingQueue又继承了Queue)并扩展了一些新方法。生产者会一直阻塞

  • 本文向大家介绍通过实例了解Javascript柯里化流程,包括了通过实例了解Javascript柯里化流程的使用技巧和注意事项,需要的朋友参考一下 函数式编程是一种如今比较流行的编程范式,它主张将函数作为参数进行传递,然后返回一个没有副作用的函数,说白了,就是希望一个函数只做一件事情。 像Javascript,Haskell,Clojure等编程语言都支持函数式编程。 这种编程思想涵盖了三个重要的

  • 本文向大家介绍通过实例了解java序列化机制,包括了通过实例了解java序列化机制的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要介绍了通过实例了解java序列化机制,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 序列化是指对象通过写出描述自己状态的数值来记录自己的过程,即将对象表示成一系列有序字节,Java提供了将对象写入流和从流中恢复对

  • 我正在将EhCache与Spring和MyBatis一起使用,需要澄清EhCache是如何工作的。我有以下ehcache的配置文件。 我只是在配置默认缓存。如果我理解正确,当你将这一行添加到MyBatis mapper文件时,它会创建一个新的缓存。 这让我想知道它是否从默认缓存继承了属性?如果不是,配置默认缓存的目的是什么? 最佳做法是为每一项功能/数据创建一个缓存,还是一个大缓存? 我还试图摆脱

  • 本文向大家介绍通过实例了解JavaBean开发及使用过程解析,包括了通过实例了解JavaBean开发及使用过程解析的使用技巧和注意事项,需要的朋友参考一下 一、JavaBean简介 JavaBean是使用Java语言开发的一个可重用的组件,在JSP的开发中可以使用JavaBean减少重复代码,使整个JSP代码的开发更简洁。JSP搭配JavaBean来使用,有以下的优点: 1.可将HTML和Java

  • 我有一个带有两个Selenium服务的Docker撰写文件: 我有另一个服务设置与量角器安装。 这是我的量角器配置文件: 这可以成功运行,但如果我将浏览器名称更改为firefox,将selenium地址更改为firefox容器,测试就会失败。 1) 选中时,includes coachcard指令应显示coachcard类型面板 消息:失败:在页面上找不到角度http://build-tool:8