We often use TableView to show a Cell,cell data from a model class that we have customized, so there are several scenarios for TableView.
1. Add action: At the top of the list page there is a button called new, click to enter a new add page, add finished, return to the list page to update the data.
2. Update operation: Click on the cell in the list to enter the edit page, the editing page is actually a display of the properties in this model class, after some of these properties are changed, return to the list page to update the data.
3. Delete operation: Click the cell in the list to enter the edit page, the page has a Delete button, click the Delete button, after the successful operation, return to the list page update data.
For the above scenario, it is generally foolish to go back to the list page and load the data again from the server, but it is too expensive to pass the resources.
Another option is to update the data source (array DataSource):
- After the add operation executes, insertobject:obj and then reload the list in the data source datasource.
- After the update operation, the data source datasource found the item to be updated and then reload the list.
- After the delete operation, the item is found in the data source DataSource and then the reload list is deleted.
To achieve this, we need to pass the data source datasource to the next page or notify DataSource (when the action is executed) by the message notification mechanism, and if the list of features in the project is very numerous, it is a bit of a hassle to repeat the operation every time, so here, I've encapsulated a tableview category to solve the above problem, and it works as follows:
1. Add registration Listener messages to TableView (adding, updating, deleting, refreshing)
- (void) Adddatachangedobserver: (Nsmutablearray *) DataSource PrimaryKey: (NSString*) PrimaryKey Changeblock: (datachangeblock) Changeblock {//associating data Source properties to categories, storing tableview data sourcesObjc_setassociatedobject (self, (__bridgeConst void*) (Kdatasource), DataSource, objc_association_retain_nonatomic); //record the unique identification of the model in the data sourceObjc_setassociatedobject (self, (__bridgeConst void*) (Kprimarykey), PrimaryKey, objc_association_copy_nonatomic); //block that records callbacksObjc_setassociatedobject (self, (__bridgeConst void*) (Kchangeblock), Changeblock, objc_association_copy_nonatomic); //Adding a listener method[self removeobserver]; [Self addobserver]; }
View Code
#pragmaMark-observer operation-(void) Addobserver {[[Nsnotificationcenter defaultcenter] addobserver:self selector: @selector (add:) Name: TableviewoperationaddnotificationObject: nil]; [[Nsnotificationcenter Defaultcenter] addobserver:self selector: @selector (delete:) Name: TableviewoperationdeletenotificationObject: nil]; [[Nsnotificationcenter Defaultcenter] addobserver:self selector: @selector (update:) Name: TableviewoperationupdatenotificationObject: nil]; [[Nsnotificationcenter Defaultcenter] addobserver:self selector: @selector (refresh:) Name: TableviewoperationrefreshnotificationObject: nil];}
View Code
2. Methods called after receiving a message notification
#pragmamark-actions-(void) Add: (Nsnotification *) Notification {NSLog (@"The Add message event for TableView was called"); IDOBJ = notification.Object; //get data source data for object AdditionsNsmutablearray *datasource =[self getpropertykey:kdatasource]; if(DataSource &&obj) { if(Datasource.count >0) { if([obj iskindofclass:[datasource[0]class]]) {[DataSource insertobject:obj Atindex:0]; [Self reloaddata]; }}} [self Callback:tableviewoperationadd obj:obj];}- (void) Delete: (Nsnotification *) Notification {NSLog (@"a TableView Delete message event was called"); IDobjnotify = notification.Object; //delete an object from the data source and refresh the TableView[self changedatasourcewithobj:objnotify operationtype:tableviewoperationdelete]; [Self Callback:tableviewoperationdelete obj:objnotify];}- (void) Update: (Nsnotification *) Notification {NSLog (@"The update message event for TableView was called"); IDobjnotify = notification.Object; //update an object from the data source and refresh the TableView[self changedatasourcewithobj:objnotify operationtype:tableviewoperationupdate]; [Self callback:tableviewoperationupdate obj:objnotify];}- (void) Refresh: (Nsnotification *) Notification {NSLog (@"The refresh message event for TableView was called"); IDOBJ = notification.Object; //Refresh TableView[self reloaddata]; [Self Callback:tableviewoperationrefresh obj:obj];}- (void) Callback: (Tableviewoperationtype) Operationtype obj: (ID) obj {datachangeblock block= Objc_getassociatedobject (self, (__bridgeConst void*) kchangeblock); Nsindexpath*indexpath = Objc_getassociatedobject (self, (__bridgeConst void*) Kindexpath); if(block) {block (Operationtype, Indexpath, obj); }}
View Code
- (void) Changedatasourcewithobj: (ID) objnotify Operationtype: (tableviewoperationtype) Operationtype {//Remove Data sourceNsmutablearray *datasource =[self getpropertykey:kdatasource]; //Remove Object primary key field nameNSString *primarykey =[self getpropertykey:kprimarykey]; //Remove the value values for the primary key field of the objectNSString *valuenotify =[self getobjpropertyvaluebykey:primarykey obj:objnotify]; if(objnotify) {[DataSource enumerateobjectsusingblock:^(IDobj, Nsuinteger idx, BOOL *stop) {NSString*value =[self getobjpropertyvaluebykey:primarykey obj:obj]; if([valuenotify Isequaltostring:value]) {if(Operationtype = =tableviewoperationdelete) {[DataSource removeobject:objnotify]; NSLog (@"object deleted successfully, refresh data"); } Else if(Operationtype = =tableviewoperationupdate) {[DataSource replaceobjectatindex:idx withobject:objnotify]; NSLog (@"object updated successfully, refresh data"); } [self reloaddata]; *stop =YES; } }]; }}
View Code
The main use of the relevant knowledge of the runtime, dynamic for the tableview associated with the property, when the program runs to perform the corresponding operation, according to the associated properties to manipulate the data source, to achieve the effect.
How to use??
1. It is very simple to add the following method to the required Viewcontroller:
[Self.tableview addDataChangedObserver:self.datasource PrimaryKey:@ "pid"ID obj) { NSLog (@ "%@", Indexpath); NSLog (@ "%ld", Operationtype); NSLog (@ "%@", obj); }];
View Code
Description: Self.datasource an initialized array that holds the data source, the identity attribute in the model object in the "pid" data source, which is the PID attribute in the person class, and the block that changblock the callback when the operation Operationtype operation type (increment, delete, change, refresh), indexpath operation Line, obj action class, here is Person object
2. Send a notification message where you need to perform the action
-(Ibaction) Delete: (ID) sender { object: SELF.P];} -(ibaction) Update: (ID) sender { = [NSString stringWithFormat:@ "change_%@ " , Self.p.name]; Object : SELF.P];}
View Code
It is not very convenient to use it.
Specific source code and demo please visit
Https://github.com/appleboyaug/UITableView-DataChanged
TableView Dynamic Update operation (no need to reload data source)