我有一个可扩展的 UITableView。当用户点击标题时,相关单元格将显示动画 (RowAnimation.Fade),然后 UITableView 滚动到该标题(展开的标题)。当用户再次点击该标题时,它会折叠。
我想要实现:我需要一个带有标题和单元格的可扩展 UITableView。当用户点击标题时,需要使用 RowAnimation.Fade 打开单元格,然后滚动到该标题。
奖励:此外,如果我可以在用户点击标题时让箭头动画,那会很棒,但我认为这会导致另一个错误,因为我们在同一个线程(主线程)上运行了太多动画
我的问题 是,当用户点击标题时,tableView 内容插入发生变化,整个标题继续减去 Y 位置。于是出现了一个奇怪的动画。 (例如,标题,看起来在单元格的中心)但是,动画完成后,一切看起来都是正确的。
func toggleSection(header: DistrictTableViewHeader, section: Int) {
self.selectedHeaderIndex = section
self.cities[section].isCollapsed = !self.cities[section].isCollapsed
let contentOffset = self.tableView.contentOffset
self.tableView.reloadSections(IndexSet(integer: section), with: UITableView.RowAnimation.fade)
self.tableView.scrollToRow(at: IndexPath(row: NSNotFound, section: section) /* you can pass NSNotFound to scroll to the top of the section even if that section has 0 rows */, at: UITableView.ScrollPosition.top, animated: true)
}
此外:我设置标题和单元格的高度如下所示。
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 1
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 60
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 140
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header: DistrictTableViewHeader = tableView.dequeueReusableHeaderFooterView(withIdentifier: headerId) as! DistrictTableViewHeader
//let header = DistrictTableViewHeader()
header.customInit(title: self.cities[section].name, section: section, delegate: self,isColapsed: self.cities[section].isCollapsed,isSelectedHeader: section == selectedHeaderIndex ? true : false)
return header
}
我的自定义 headerView 类:
protocol ExpandableHeaderViewDelegate {
func toggleSection(header: DistrictTableViewHeader, section: Int)
}
class DistrictTableViewHeader: UITableViewHeaderFooterView {
var delegate: ExpandableHeaderViewDelegate?
var section: Int!
let nameLabel: UILabel = {
let l = UILabel()
l.textColor = Color.DistrictsPage.headerTextColor
return l
}()
private let arrowImage: UIImageView = {
let i = UIImageView()
let image = UIImage(named: "ileri")?.withRenderingMode(UIImage.RenderingMode.alwaysTemplate)
i.image = image
i.contentMode = .scaleAspectFit
return i
}()
var willAnimate: Bool = false
var isColapsed: Bool!{
didSet{
expandCollapseHeader()
}
}
private func expandCollapseHeader(){
if(willAnimate){
if(!self.isColapsed){
let degrees : Double = 90 //the value in degrees
self.nameLabel.textColor = Color.Common.garantiLightGreen
self.arrowImage.tintColor = Color.Common.garantiLightGreen
self.arrowImage.transform = CGAffineTransform.init(rotationAngle: CGFloat(degrees * .pi/180))
self.contentView.backgroundColor = UIColor(red:0.97, green:0.97, blue:0.97, alpha:1.0)
}else{
let degrees : Double = 0 //the value in degrees
self.nameLabel.textColor = Color.DistrictsPage.headerTextColor
self.arrowImage.tintColor = UIColor.black
self.arrowImage.transform = CGAffineTransform.init(rotationAngle: CGFloat(degrees * .pi/180))
self.contentView.backgroundColor = UIColor.white
}
}else{
if(!isColapsed){
let degrees : Double = 90 //the value in degrees
self.nameLabel.textColor = Color.Common.garantiLightGreen
self.arrowImage.tintColor = Color.Common.garantiLightGreen
self.arrowImage.transform = CGAffineTransform.init(rotationAngle: CGFloat(degrees * .pi/180))
self.contentView.backgroundColor = UIColor(red:0.97, green:0.97, blue:0.97, alpha:1.0)
}else{
let degrees : Double = 0 //the value in degrees
self.nameLabel.textColor = Color.DistrictsPage.headerTextColor
self.arrowImage.tintColor = UIColor.black
self.arrowImage.transform = CGAffineTransform.init(rotationAngle: CGFloat(degrees * .pi/180))
self.contentView.backgroundColor = UIColor.white
}
layoutSubviews()
}
}
override init(reuseIdentifier: String?) {
super.init(reuseIdentifier: reuseIdentifier)
self.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(selectHeaderAction)))
nameLabel.translatesAutoresizingMaskIntoConstraints = false
nameLabel.font = UIFont.systemFont(ofSize: 22)
nameLabel.textColor = Color.DistrictsPage.headerTextColor
contentView.addSubview(nameLabel)
nameLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
nameLabel.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 15).isActive = true
arrowImage.tintColor = UIColor(red:0.32, green:0.36, blue:0.36, alpha:1.0)
arrowImage.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(arrowImage)
arrowImage.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
arrowImage.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -20).isActive = true
arrowImage.widthAnchor.constraint(equalToConstant: 20).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func rotate(_ toValue: CGFloat) {
self.transform = CGAffineTransform.init(rotationAngle: toValue)
}
@objc func selectHeaderAction(gestureRecognizer: UITapGestureRecognizer) {
let cell = gestureRecognizer.view as! DistrictTableViewHeader
delegate?.toggleSection(header: self, section: cell.section)
}
func customInit(title: String, section: Int, delegate: ExpandableHeaderViewDelegate,isColapsed: Bool, isSelectedHeader: Bool) {
self.nameLabel.text = title
self.nameLabel.accessibilityIdentifier = title
self.section = section
self.delegate = delegate
self.willAnimate = isSelectedHeader
self.isColapsed = isColapsed
}
override func layoutSubviews() {
super.layoutSubviews()
self.contentView.backgroundColor = UIColor.white
}
}
在下图中,可以清楚地看到错误。当“一些数据”和“另一个城市”打开时,你点击“一些数据”。出现动画错误。 “另一座城市”在它的牢房之上,然后上升。应该做的是“另一个城市”应该留在它的位置,然后在“一些数据”单元格关闭时向上移动。
示例项目: https://github.com/emreond/tableViewLayoutIssue
最佳答案
经过几天的搜索和尝试,我发现将 UITableViewStyle 更改为组可以解决问题。因此,我将初始化 UITableView 更改为
let tableView = UITableView.init(frame: CGRect.zero, style: .grouped)
除了滚动,我还需要添加 CATransaction 来捕获完成。
CATransaction.begin()
DispatchQueue.main.async {
self.tableView.beginUpdates()
CATransaction.setCompletionBlock {
// Code to be executed upon completion
self.tableView.scrollToRow(at: IndexPath(row: NSNotFound, section: section) /* you can pass NSNotFound to scroll to the top of the section even if that section has 0 rows */, at: UITableView.ScrollPosition.top, animated: true)
}
self.tableView.reloadSections(IndexSet.init(integer: section), with: UITableView.RowAnimation.fade)
self.tableView.endUpdates()
}
CATransaction.commit()
}
关于ios - UITableView 重新加载部分时内容插入更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54396464/
如何正确创建Rails迁移,以便将表更改为MySQL中的MyISAM?目前是InnoDB。运行原始执行语句会更改表,但它不会更新db/schema.rb,因此当在测试环境中重新创建表时,它会返回到InnoDB并且我的全文搜索失败。我如何着手更改/添加迁移,以便将现有表修改为MyISAM并更新schema.rb,以便我的数据库和相应的测试数据库得到相应更新? 最佳答案 我没有找到执行此操作的好方法。您可以像有人建议的那样更改您的schema.rb,然后运行:rakedb:schema:load,但是,这将覆盖您的数据。我的做法是(假设
我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]
鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende
我正在使用active_admin,我在Rails3应用程序的应用程序中有一个目录管理,其中包含模型和页面的声明。时不时地我也有一个类,当那个类有一个常量时,就像这样:classFooBAR="bar"end然后,我在每个必须在我的Rails应用程序中重新加载一些代码的请求中收到此警告:/Users/pupeno/helloworld/app/admin/billing.rb:12:warning:alreadyinitializedconstantBAR知道发生了什么以及如何避免这些警告吗? 最佳答案 在纯Ruby中:classA
我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘
我尝试使用不同的ssh_options在同一阶段运行capistranov.3任务。我的production.rb说:set:stage,:productionset:user,'deploy'set:ssh_options,{user:'deploy'}通过此配置,capistrano与用户deploy连接,这对于其余的任务是正确的。但是我需要将它连接到服务器中配置良好的an_other_user以完成一项特定任务。然后我的食谱说:...taskswithoriginaluser...task:my_task_with_an_other_userdoset:user,'an_othe
我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
这里有一个很好的答案解释了如何在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返回它复制的字节数,但是当我还没有下
我正在尝试解析一个CSV文件并使用SQL命令自动为其创建一个表。CSV中的第一行给出了列标题。但我需要推断每个列的类型。Ruby中是否有任何函数可以找到每个字段中内容的类型。例如,CSV行:"12012","Test","1233.22","12:21:22","10/10/2009"应该产生像这样的类型['integer','string','float','time','date']谢谢! 最佳答案 require'time'defto_something(str)if(num=Integer(str)rescueFloat(s