【问题标题】:UIButton | setTitle taking huge amount of time even in main thread按钮 | setTitle 即使在主线程中也需要大量时间
【发布时间】:2016-08-16 00:49:45
【问题描述】:

我重新打开这个问题是因为我的最后一个问题被标记为重复,即使它实际上不是!这是同样的问题,但解决方案不适用于我的代码。我正在使用 swift 2。

所以我的问题是,正如标题所说:我在 tableViewCell 中有一个 UIButton,当我使用方法 «setTitle » 时,更新标题需要 10 到 60 秒。同时我正在使用 « addTarget » 它可以立即运行。所以标题也应该更新。我的按钮在我的故事板中设置为“自定义”。

当视图加载时,我正在运行以下代码:

/* viewDidLoad */

override func viewDidLoad() {
    super.viewDidLoad() 
    boolAlready = false 
    findParticipation() 
}

/* 查找参与 */

func findParticipation() {
    // After server request response :
    boolAlready = true 
    self.tableView.reloadData() 
}

/* cellForRowAtIndexPath */

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    let cellActions = tableView.dequeueReusableCellWithIdentifier(informationsCellArray[indexPath.row], forIndexPath: indexPath) as     ! eventDetailsAction

    if boolAlready { 
         cellActions.foundParticipation
    } else { 

        cellActions.btnParticipate.setTitle("...", forState: UIControlState.Normal)
        cellActions.btnParticipate.addTarget(self, action: « deleteParticion", forControlEvents: .TouchUpInside)
} 

/* 在我的自定义单元格中 */

func foundParticipation () {
    self.btnParticipate.setTitle("Annuler", forState: UIControlState.Normal)
    self.btnParticipate.addTarget(self, action: "deleteParticipation", forControlEvents: .TouchUpInside)
}

我在论坛上发现了一些不起作用的东西:

  1. 设置我的 settitle 动作 dispatch_async(dispatch_get_main_queue()) {}

  2. 为所有不同的 UIControlStates 设置标题

  3. 使用setAttributedTitle()

  4. 在setTitle之后使用self.btnParticipate.setNeedsLayout()self.btnParticipate.layoutIfNeeded()

  5. 在setTitle之前禁用按钮并在setTitle之后启用它

  6. self.addSubview(self.btnParticipate)

  7. 更改titleLabel.text中的标题

  8. 使用cellActions.btnParticipate在父视图控制器中执行前面所说的所有操作

  9. UIView.performWithoutAnimation { self.btnParticipate.setTitle("Annuler", forState: .Normal) }

我现在陷入困境,找不到解决方案。

【问题讨论】:

  • 那么,foundParticipation() 方法总是在主线程上调用?
  • 是的,它只在由tableView.reloadData 触发的cellForRowAtIndexPath 中调用。而且你只能在主线程中使用tableView.reloadData

标签: ios swift uibutton delay


【解决方案1】:

你可以尝试参考这个答案https://stackoverflow.com/a/29633647/4478037

确保您的按钮是“自定义”按钮而不是“系统”按钮。

【讨论】:

    【解决方案2】:

    尝试将您的setTitle 调用封装到performWithoutAnimation

    UIView.performWithoutAnimation {
        self.btnParticipate.setTitle("Annuler", forState: .Normal)
    }
    

    【讨论】:

    • 这似乎没有任何改变。
    【解决方案3】:

    您的问题是,当您创建单元格时,btnParticipate 函数将无法正常运行,您必须在 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) 方法中编写所有这些条件

    试试这个

    let cellActions = tableView.dequeueReusableCellWithIdentifier(informationsCellArray[indexPath.row], forIndexPath: indexPath) as     ! eventDetailsAction
    
             cellActions.removeTarget(nil, action: nil, forControlEvents: .AllEvents)
    
             if boolAlready {
                cellActions.btnParticipate.setTitle("Annuler", forState: UIControlState.Normal)
                cellActions.btnParticipate.addTarget(self, action: "deleteParticipation", forControlEvents: .TouchUpInside)
             } else {
    
                cellActions.btnParticipate.setTitle("...", forState: UIControlState.Normal)
                cellActions.btnParticipate.addTarget(self, action: « deleteParticion", forControlEvents: .TouchUpInside)
             }
    

    【讨论】:

    • 两种方法我都试过了,时间也一样。
    【解决方案4】:

    你可以使用

    reloadRowsAtIndexPaths(_:withRowAnimation:)
    

    强制重新加载单元格。

    当标题更改时,这意味着您的代码似乎是正确的并且它与渲染周期有关。这将是重新加载单元格的一种方法。

    供参考:Apple Docs - UITableView reloadRowsAtIndexPaths

    编辑:


    当某些事件被触发、请求完成等时,您必须调用此方法来更新单元格。我再次查看了您的代码,似乎您的 if-else in cell for row at index path 没有做它应该做的事情。你不应该称之为任何“执行动作的方法”。它只是用于初始化。

    您的问题似乎是您的布尔值 boolAlready 对于所有单元格都是相同的。这将导致永远不会执行 else 块。因此,没有设置标题,或者只是在布尔设置为 false 时设置了标题。您可能应该在那里打印布尔值。和/或使用更多信息更新您的帖子。

    当您使用几乎相同的名称(如 findParticipation 和 foundParticipation)时,它的代码可读性不好。您可能应该重构它。

    【讨论】:

    • 此解决方案不起作用。但我不确定我是否正确使用它。我所做的是在创建单元格时,将 indexPath 添加到传递给 UITableViewCell 的数组中,然后在 setTitle 之后运行该方法。
    【解决方案5】:

    所以经过 1 周的尝试后,我决定停止搜索... 我只是同步调用 findParticipation() 并且在得到 findParticipation() 响应之前我不会实例化我的 tableView。

    我知道这对于用户体验来说更糟,但等待的时间仍然更少。

    【讨论】:

      猜你喜欢
      • 2016-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-21
      • 2016-05-20
      • 1970-01-01
      • 2019-10-27
      • 2021-05-28
      相关资源
      最近更新 更多