如何在运行时正确修改iOS表视图单元格(添加/删除子视图?)

时间:2015-08-01 13:01:41

标签: ios iphone swift uitableview

如果已在某处回答,请提前道歉。我到处寻找,我仍然不确定该怎么做。 (使用Objective C的答案对我来说几乎完全没用。)我对iOS有点新鲜。

我有一个UITableView作为各种新闻源,显示一系列帖子。 (例如,一个Twitter新闻源。)此表视图中的单元格(当前)来自在xcode的界面构建器中创建的单个单元格原型。每个单元格都包含子视图,以显示用户名,个人资料图片缩略图,标题,消息,日期,位置,其他图像等内容。

问题是,根据特定帖子包含的数据,许多这些子视图应该或不应该显示 - 如果帖子不包含图像,则不应显示该单元格的图像视图;如果帖子没有日期和/或位置,则不应显示其中一个或两个视图。不使用的字段不仅应为空,而且不应占用单元格中的任何空间。

我在Using Auto Layout in UITableView for dynamic cell layouts & variable row heights中阅读(在“2.确定独特的表格查看单元格重用标识符”下。@ smileyborg的精彩回答,顺便说一下。)对于可能在单元格中的每个不同的子视图布局,不同的应使用原型单元和重用标识符。但这需要我为帖子中的每个可能的数据项组合设置一个单元格原型,即使差异是单个标签!当然必须有更好的方法。

做我需要做的事情的安全和正确方法是什么?是否有一种方法可以在运行时从单元格中删除子视图(并使布局相应地调整其间距),而不会完全搞砸细胞回收?

1 个答案:

答案 0 :(得分:3)

Ill假设您在看到单元格时知道有关布局的所有信息。

所以它的基本tableview单元格布局。出列并装饰。

function sendMessage(userId, to, subject, email) {
    authUser(function() {
        var base64EncodedEmail = btoa(email);
        var request = gapi.client.gmail.users.messages.send({
            'userId': userId,
            'message': {
                'raw': base64EncodedEmail,
                'headers': [
                    {'To': to}, 
                    {'Subject': subject}
                ]
            }
        });
        request.execute();
    });
}

function authUser(callback) {
    chrome.identity.getAuthToken({'interactive': true}, function(token) {
        // load Google's javascript client libraries
        var url = "https://www.googleapis.com/gmail/v1/users/me/messages/send?access_token=" + token;
        var request = new XMLHttpRequest();
        request.onreadystatechange = function() {
            if (request.readyState !== 4 || request.status !== 200) {
                return;
            }
            var response = JSON.parse(request.responseText);
            console.log(response);
            callback();
        }
        ;
        request.open('POST', url, true);
        request.send();
        request.setRequestHeader('Authorization', 'Bearer ' + token);
    });
}

但您还需要让细胞正确设置其高度

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier(MyIdentifier, forIndexPath: indexPath) as! MyCustomCellClass

    let data:MyDataClass = myDataAtIndexPath(indexPath)

    decorateCell(cell,data:data)

    return cell
}

func decorateCell(cell:MyCustomCellClass,data:MyDataClass) {

    //here is where you arrange/change your constraints and hide/reveal views
    //depending on the data
}

但最重要的是在你的XIB中,单元格必须从上到下有一个连续约束线来描述高度。

因此,此单元格将自动正确设置其高度。

enter image description here

虽然这不会。

enter image description here

注意 - 在上面的示例中,如果您将高度约束保留在文本字段之外并使其无限行计数,则单元格将适当地增大/缩小。

总而言之,只要您保持高度限制一致,就可以使用一个多用途细胞。

作为一般规则 - 做很多事情的 SwissArmyCells®可能会有点笨拙,所以你需要考虑一个单元格中你希望支持多少个用例,然后才能启动创建多个类型/标识符。