SWIFT
我需要制作一个单元格数组。我有几个带有 nib 文件的自定义单元格类(继承自 UITableViewCell)。
如何在不在 tableview 中注册 nib 并执行 dequeueReusableCellWithIdentifier 的情况下初始化单元格? 我是这样做的,但不要认为它会起作用:
var labelCell = CustomCellClass.initialize()
最佳答案
我从其他地方的评论中的讨论中推断,您不想让单元格出列和重用的原因是您无法跟踪单元格中捕获的用户输入。
最重要的是,您确实应该允许单元格出队和重用,并适本地处理它。如果您在重复使用单元格时遇到问题,可以通过将“模型”(即您的数据)与“ View ”(即 UIKit 控件)分开来解决。这就是精神model-view-controller pattern ,但在任何具有关注点分离的模式中都是如此(例如,MVVP、MVP 等)。
关键是,当单元格中的值发生变化时,您的单元格应立即通知 View Controller ,以便 View Controller 可以立即更新模型。然后,当 View Controller 稍后需要对与特定行关联的值执行某些操作时,它不会从单元格中检索它,而是从它自己的模型中检索。
因此,我可能会为单元格定义一个协议(protocol),以通知 TableView 其文本字段已更改:
protocol CustomCellDelegate: class {
func cell(_ cell: CustomCell, didUpdateTextField textField: UITextField)
}
然后我将定义一个调用该委托(delegate)的单元类:
class CustomCell: UITableViewCell {
weak var delegate: CustomCellDelegate?
@IBOutlet weak var customTextField: UITextField! // hook up outlet to this property in IB
@IBAction func didChangeValue(_ sender: UITextField) { // hook up "editing changed" action for the text field to this method in IB
delegate?.cell(self, didUpdateTextField: sender)
}
}
现在, View Controller 将:
cellForRowAt 中,填充文本字段并将其自身指定为该单元格的委托(delegate);和didUpdateTextField 方法以在用户更改任何内容时更新模型。因此,类似于:
class ViewController: UITableViewController {
var values = ["One", "Two", "Three"] // some initial values
private let cellIdentifier = "CustomCell"
override func viewDidLoad() {
super.viewDidLoad()
// if you’re using NIBs, you register them.
// obviously if using prototype cells in your storyboard, this isn’t necessary.
tableView.register(UINib(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: cellIdentifier) // or use cell prototype with storyboard identifer specified
}
}
// MARK: - UITableViewDataSource
extension ViewController {
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return values.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! CustomCell
// populate cell and specify delegate
cell.delegate = self
cell.customTextField.text = values[indexPath.row]
return cell
}
}
// MARK: - CustomCellDelegate
extension ViewController: CustomCellDelegate {
func cell(_ cell: CustomCell, didUpdateTextField textField: UITextField) {
// when the cell tells us that its text field's value changed, update our own model
if let indexPath = tableView.indexPath(for: cell), let string = textField.text {
values[indexPath.row] = string
}
}
}
许多人可能倾向于通过将文本字段的 IBAction 直接挂接到 View Controller 方法来进一步简化它。这行得通,并且消除了对这个协议(protocol)的需要,但问题是你需要弄清楚这个特定的 UIKit 控件与哪一行相关联。常见的技巧是向上导航 View 层次结构以识别适当的单元格(例如,文本字段通常位于单元格内的内容 View 中,因此您可以将 textField.superview.superview as!UITableViewCell 抓取) ,但这对我来说有点脆弱。
但不管这个小细节如何,希望这能说明更广泛的模式。与其试图让单元格跟踪用户输入,不如让单元格(“ View ”)立即更新 Controller 的任何数据更改,然后 View Controller 立即更新模型,你不再需要担心iOS 采用的单元重用优化。
有关 Swift 2 版本,请参阅 previous revision of this answer .
关于ios - 从没有 dequeueReusableCellWithIdentifier 的 nib 初始化自定义 UITableViewCell,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38269248/
我正在尝试设置一个puppet节点,但rubygems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由rubygems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby
在我的gem中,我需要yaml并且在我的本地计算机上运行良好。但是在将我的gem推送到rubygems.org之后,当我尝试使用我的gem时,我收到一条错误消息=>"uninitializedconstantPsych::Syck(NameError)"谁能帮我解决这个问题?附言RubyVersion=>ruby1.9.2,GemVersion=>1.6.2,Bundlerversion=>1.0.15 最佳答案 经过几个小时的研究,我发现=>“YAML使用未维护的Syck库,而Psych使用现代的LibYAML”因此,为了解决
我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer
我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢
我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby1.9+ 关于ruby-主要:Objectwhenrun
我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
我有一个只接受一个参数的方法:defmy_method(number)end如果使用number调用方法,我该如何引发错误??通常,我如何定义方法参数的条件?比如我想在调用的时候报错:my_method(1) 最佳答案 您可以添加guard在函数的开头,如果参数无效则引发异常。例如:defmy_method(number)failArgumentError,"Inputshouldbegreaterthanorequalto2"ifnumbereputse.messageend#=>Inputshouldbegreaterthano
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下
我使用Ember作为我的前端和GrapeAPI来为我的API提供服务。前端发送类似:{"service"=>{"name"=>"Name","duration"=>"30","user"=>nil,"organization"=>"org","category"=>nil,"description"=>"description","disabled"=>true,"color"=>nil,"availabilities"=>[{"day"=>"Saturday","enabled"=>false,"timeSlots"=>[{"startAt"=>"09:00AM","endAt"=>