Swift - 动态添加删除TableView的单元格(以及内部元件-日期控件)

原帖:http://www.hangge.com/blog/cache/detail_727.html

在Swift开发中,我们有时需要动态的添加或删除列表的单元格。

 
比如我们做一个消息提醒页面,默认页面只显示两个单元格。当点击第二个单元格(时间标签)时,下面会再添加一个单元格放置日期选择控件(同时新增单元格的高度也会变化)。而再次点击第二个单元格,日期选择控件又会隐藏。

   
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import  UIKit
 
class  MyTableViewController UITableViewController  {
     
     @IBOutlet  weak  var  dueDateLabel:  UILabel !
     
     //日期选择器显示状态
     var  datePickerVisible: Bool  false
 
     override  func  viewDidLoad() {
         super .viewDidLoad()
       
         self .title =  "添加任务"
         //去除尾部多余的空行
         self .tableView.tableFooterView =  UIView (frame: CGRectZero )
     }
 
     override  func  didReceiveMemoryWarning() {
         super .didReceiveMemoryWarning()
     }
     
     //选择cell的row之后
     override  func  tableView(tableView:  UITableView , didSelectRowAtIndexPath indexPath:  NSIndexPath ) {
         self .tableView.deselectRowAtIndexPath(indexPath, animated:  true )
        
         //当执行到日期选择器上一行的时候,可以判断是否要显示日期选择器了
         if  indexPath.section == 0 && indexPath.row == 1{
             if  !datePickerVisible{
                 self .showDatePicker()
             } else {
                 self .hideDatePicker()
             }
         }
         
         println (indexPath.row)
     }
     
     //显示日期选择器
     func  showDatePicker(){
         //日期选择器的状态设为打开
         datePickerVisible =  true
         
         let  indexPathDatePicker =  NSIndexPath (forRow: 2, inSection: 0)
         self .tableView.insertRowsAtIndexPaths([indexPathDatePicker],
             withRowAnimation:  UITableViewRowAnimation . Automatic )
         
     }
     
     //隐藏日期选择器
     func  hideDatePicker(){
         if  datePickerVisible {
             //日期选择器的状态设为关闭
             datePickerVisible =  false
             let  indexPathDatePicker =  NSIndexPath (forRow: 2, inSection: 0)
             self .tableView.deleteRowsAtIndexPaths([indexPathDatePicker],
                 withRowAnimation:  UITableViewRowAnimation . Fade )
         }
     }
 
     override  func  numberOfSectionsInTableView(tableView:  UITableView ) ->  Int  {
         return  1
     }
     
     //设置cell
     override  func  tableView(tableView:  UITableView , cellForRowAtIndexPath indexPath:  NSIndexPath )
         ->  UITableViewCell  {
         //因为日期选择器的位置在日期显示Label下面。它的位置就是第2个section  和第3个row
         if  indexPath.section == 0 && indexPath.row == 2{
             //用重用的方式获取标识为DatePickerCell的cell
             var  cell = tableView.dequeueReusableCellWithIdentifier( "DatePickerCell" )
                 as  UITableViewCell ?
             //如果没找到就创建一个
             if  cell ==  nil  {
                 //创建一个标识为DatePickerCell的cell
                 cell =  UITableViewCell (style:  UITableViewCellStyle . Default ,
                     reuseIdentifier:  "DatePickerCell" )
                 //设置cell的样式
                 cell?.selectionStyle =  UITableViewCellSelectionStyle . None
                 //创建日期选择器
                 var  datePicker =  UIDatePicker (frame:  CGRectMake (0.0, 0.0, 320.0, 216.0))
                 //给日期选择器的tag
                 datePicker.tag = 100
                 //将日期选择器区域设置为中文,则选择器日期显示为中文
                 datePicker.locale =  NSLocale (localeIdentifier:  "zh_CN" )
                 //将日期选择器加入cell
                 cell?.contentView.addSubview(datePicker)
                 //注意:action里面的方法名后面需要加个冒号“:”
                 datePicker.addTarget( self , action:  "dateChanged:" ,
                     forControlEvents:  UIControlEvents . ValueChanged )
             }
             return  cell!
         } else {
             return  super .tableView(tableView, cellForRowAtIndexPath: indexPath)
         }
     }
     
     //日期选择器响应方法
     func  dateChanged(datePicker :  UIDatePicker ){
         //更新提醒时间文本框
         let  formatter =  NSDateFormatter ()
         //日期样式
         formatter.dateFormat =  "yyyy年MM月dd日 HH:mm:ss"
         self .dueDateLabel.text = formatter.stringFromDate(datePicker.date)
     }
 
     //根据日期选择器的隐藏与否决定返回的row的数量
     override  func  tableView(tableView:  UITableView , numberOfRowsInSection section:  Int ) ->  Int  {
         
         if  section == 0  && datePickerVisible{
             return  3
         } else {
             return  super .tableView(tableView, numberOfRowsInSection: section)
             
         }
     }
 
     //因为日期选择器插入后会引起cell高度的变化,所以要重新设置
     override  func  tableView(tableView:  UITableView ,
         heightForRowAtIndexPath indexPath:  NSIndexPath ) ->  CGFloat  {
         //当渲染到达日期选择器所在的cell的时候将cell的高度设为217
         if  indexPath.section == 0 && indexPath.row == 2{
             return  216.0
         } else {
             return  super .tableView(tableView, heightForRowAtIndexPath: indexPath)
         }
     }
 
     //当覆盖了静态的cell数据源方法时需要提供一个代理方法。
     //因为数据源对新加进来的日期选择器的cell一无所知,所以要使用这个代理方法
     override  func  tableView(tableView:  UITableView ,
         indentationLevelForRowAtIndexPath indexPath:  NSIndexPath ) ->  Int  {
         if  indexPath.section == 0 && indexPath.row == 2{
             //当执行到日期选择器所在的indexPath就创建一个indexPath然后强插
             let  newIndexPath =  NSIndexPath (forRow: 0, inSection: indexPath.section)
             return  super .tableView(tableView, indentationLevelForRowAtIndexPath: newIndexPath)
         } else {
             return  super .tableView(tableView, indentationLevelForRowAtIndexPath: indexPath)
         }
     }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Qt中使用QTableView来显示自定义件的单元,可以通过使用QItemDelegate类来实现。 首先,创建一个继承自QItemDelegate的自定义代理类,在这个类中重写createEditor()方法和setEditorData()方法。在createEditor()方法中,可以创建并返回要在单元中显示的自定义件实例。例如,可以创建一个QLineEdit件来显示文本。在setEditorData()方法中,可以从模型中获取数据,并将其设置到编辑器中。 然后,使用setCellWidget()方法将自定义代理类应用到特定的单元中。这个方法需要传入要显示的自定义件实例、要设置的行号和列号。 最后,将自定义代理类设置为QTableView的默认代理类,以使其在整个表中生效。使用setItemDelegate()方法,将自定义代理类对象作为参数传入。 以下是一个简单的示例代码: ```cpp #include <QApplication> #include <QTableView> #include <QLineEdit> #include <QStandardItemModel> #include <QItemDelegate> class CustomDelegate : public QItemDelegate { public: QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override { QLineEdit *editor = new QLineEdit(parent); return editor; } void setEditorData(QWidget *editor, const QModelIndex &index) const override { QString data = index.model()->data(index, Qt::DisplayRole).toString(); QLineEdit *lineEdit = static_cast<QLineEdit*>(editor); lineEdit->setText(data); } }; int main(int argc, char *argv[]) { QApplication a(argc, argv); QTableView tableView; QStandardItemModel model(4, 2); tableView.setModel(&model); CustomDelegate customDelegate; tableView.setItemDelegate(&customDelegate); QLineEdit *customWidget = new QLineEdit(); tableView.setIndexWidget(model.index(1, 1), customWidget); tableView.show(); return a.exec(); } ``` 这个示例中,创建了一个QTableView并设置其模型为QStandardItemModel。然后,创建了一个自定义的代理类CustomDelegate,并将其设置为QTableView的默认代理类。然后,使用setIndexWidget()方法将自定义件QLineEdit添加到特定的单元中(在此例中,第2行第2列的单元)。最后,展示了QTableView。 当运行程序时,你会看到QTableView中的特定单元中显示了一个自定义的QLineEdit件。你也可以根据自己的需要,修改代理类中createEditor()方法和setEditorData()方法的实现,来满足其他自定义件的显示要求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值