【问题标题】:How to create a "LIKE" button on a cell and conform to MVC?如何在单元格上创建“LIKE”按钮并符合 MVC?
【发布时间】:2017-02-24 20:05:36
【问题描述】:

我想在表格视图单元格上创建一个赞按钮,就像 Instagram、Facebook 和 100 多个其他社交网络应用程序一样,但我很难理解如何在记住 MVC 范式的情况下正确完成此操作。

我的结构是这样的:

Model - FeedPost class 
View - FeedCell class (UITableViewCell subclass)
Controller - FeedTableViewController class (UITableViewController subclass)

首先想到的是执行以下操作:

在 FeedCell.swift 中:

@IBAction func likeButtonPressed(_ sender: AnyObject) {
    if let button = sender as? UIButton {
        post.like(completed: {
            if(completed){
                button.isSelected = !button.isSelected
            }
        })
    }
}

在 FeedPost.class 中:

func like(completed: (Bool) -> Void ) {
        //Make a request to a server and when it is done call
        completed(true)
    }

但这肯定会破坏 MVC 模式,因为我从视图中访问我的模型。所以我可能想通过视图控制器处理我的数据和视图。视图控制器存储帖子数组。所以我想做以下事情: - 响应用户按下表格视图单元格上的按钮 - 找出喜欢的帖子 - 执行传递帖子 ID 或任何其他引用的服务器请求 - 成功完成请求后,将按钮状态更改为选中

在遵循 MVC 模式的同时,您将如何做到这一点?

任何以正确方式完成的示例或开源项目都将受到高度赞赏。

【问题讨论】:

  • stackoverflow.com/a/40058685/6656894检查我的这个答案同样的问题已经问过
  • 您可以使用 tableview 委托方法 didSelectRowAtIndexPath 访问正确的帖子。
  • @HimanshuMoradiya 好的,我想我从你的帖子中得到了正确的想法。唯一的事情是,我想最好使用 indexPathForCell 方法而不是 indexPathForRowAtPoint
  • 你。尝试一下,如果遇到任何问题,请使用 tableview delegates 方法更新您的问题。我会解决的
  • 我会选择委托,这是一种在 Apple 的 API 中非常流行的模式。看我的回答。

标签: ios swift uitableview model-view-controller


【解决方案1】:

采用既定的 Apple 委托模式。与其在视图中处理按钮点击,不如让 like 按钮公开具有已建立协议的委托属性。然后让您的控制器实现该协议并将控制器设置为每个按钮的委托。然后,您的控制器将访问模型并在完成后更新视图。

【讨论】:

    【解决方案2】:

    比如:

    FeedCell.swift:

    @IBOutlet var likeButton: UIButton!
    var likeButtonPressedHandler: (() -> ())?
    var isLikeButtonSelected: Bool {
       get { return likeButton.isSelected }
       set { likeButton.isSelected = newValue }
    }
    @IBAction func likeButtonPressed(_ button: UIButton) {
        likeButtonPressedHandler?()
    }
    

    FeedPost.class:

    func like(completion: (Bool) -> Void ) {
        //Make a request to a server and when it is done call
        completion(true)
    }
    

    视图控制器(UITableViewDataSource):

    var posts: [FeedPost]
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier", for: indexPath) as? FeedCell
        let post = posts[indexPath.row]
        cell.isLikeButtonSelected = post.isLiked
        cell.likeButtonPressedHandler = { [weak cell] in
            post.like { completed in
                if let cell = cell where completed {
                    cell.isLikeButtonSelected = !cell.isLikeButtonSelected
                }
            })
        }
        return cell
    }
    

    【讨论】:

    • 抱歉,没看懂,你从哪里得到帖子的参考?
    • 没有参考。我只是将模型的更新/通知逻辑从视图移动到视图控制器。因为正如您所说,您不想从视图中访问模型
    • 是的,但我怎么知道我正在访问哪个帖子?这些帖子在一个数组中,那么我怎么知道我需要哪个数组元素?
    • 对不起。我误解了你。更新了我的答案
    • 好的,我们的想法是将闭包传递给每个执行逻辑的单元格。我的意思是它有效,我不认为这会破坏 MVC,但感觉有点奇怪。您是否有以这种方式完成的示例/教程/开源项目?我只是好奇这种方法的优缺点是什么。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多