UITableView(Inserting and Deleting Rows and Sections)
2013-05-16 21:58
274 查看
InsertingandDeletingRowsandSections
Atableviewhasaneditingmodeaswellasitsnormal(selection)mode.Whenatableviewgoesintoeditingmode,itdisplaystheeditingandreorderingcontrolsassociatedwithitsrows.Theeditingcontrols,whichareintheleftsideoftherow,allowtheusertoinsertanddeleterowsinthetableview.Theeditingcontrolshavedistinctiveappearances:
Deletioncontrol | |
Insertioncontrol |
Thesemethodsallowthedatasourceanddelegatetorefinetheappearanceandbehaviorofrowsinthetableview;themessagesalsoenablethemtocarryoutthedeletionorinsertionoperation.
Evenifatableviewisnotineditingmode,youcaninsertordeleteanumberofrowsorsectionsasagroupandhavethoseoperationsanimated.
Thefirstsectionbelowshowsyouhow,whenatableisineditingmode,toinsertnewrowsanddeleteexistingrowsinatableviewinresponsetouseractions.Thesecondsection,“Batch
Insertion,Deletion,andReloadingofRowsandSections,”discusseshowyoucaninsertanddeletemultiplesectionsandrowsanimatedasagroup.
Note:Theprocedureforreorderingrowswhenineditingmodeisdescribedin“Managing
theReorderingofRows.”
InsertingandDeletingRowsinEditingMode
WhenaTableViewisEdited
Atableviewgoesintoeditingmodewhenitreceivesamessage.setEditing:animated:
Typically(butnotnecessarily)themessageoriginatesasanactionmessagesentwhentheusertapsanEditbuttoninthenavigationbar.Ineditingmode,atableviewdisplaysanyediting(andreordering)controlsthatitsdelegatehas
assignedtoeachrow.Thedelegateassignsthecontrolsasaresultofreturningtheeditingstyleforarowinthe
method.tableView:editingStyleForRowAtIndexPath:
Note:Ifa
objectUIViewController
ismanagingthetableview,itautomaticallyreceivesa
setEditing:animated:messagewhentheEditbuttonistapped.Initsimplementationofthismessage,itcanupdatebutton
stateordoanyotherkindoftaskbeforeinvokingthetableview’sversionofthemethod.
Whenthetableviewreceives
,setEditing:animated:
itsendsthesamemessagetothe
objectUITableViewCell
foreachvisiblerow.Thenitsendsasuccessionofmessagestoitsdatasourceanditsdelegate(iftheyimplementthemethods)asdepictedinthediagraminFigure
7-1.
Figure7-1Callingsequencefor
insertingordeletingrowsinatableview
Afterresending
tosetEditing:animated:
thecellscorrespondingtothevisiblerows,thesequenceofmessagesisasfollows:
Thetableviewinvokesthe
methodtableView:canEditRowAtIndexPath:
ifitsdatasourceimplementsit.Thismethodallowstheapplicationtoexcluderowsinthetableviewfrombeingeditedevenwhentheircell’s
propertyeditingStyle
indicatesotherwise.Mostapplicationsdonotneedtoimplementthismethod.
Thetableviewinvokesthe
methodtableView:editingStyleForRowAtIndexPath:
ifitsdelegateimplementsit.Thismethodallowstheapplicationtospecifyarow’seditingstyleandthustheeditingcontrolthattherowdisplays.
Atthispoint,thetableviewisfullyineditingmode.Itdisplaystheinsertionordeletioncontrolforeacheligiblerow.
Theusertapsaneditingcontrol(eitherthedeletioncontrolortheinsertioncontrol).Ifheorshetapsadeletioncontrol,aDeletebuttonisdisplayedontherow.Theuserthentapsthat
buttontoconfirmthedeletion.
Thetableviewsendsthe
messagetableView:commitEditingStyle:forRowAtIndexPath:
tothedatasource.Althoughthisprotocolmethodismarkedasoptional,thedatasourcemustimplementitifitwantstoinsertordeletearow.Itmustdotwothings:
Send
ordeleteRowsAtIndexPaths:withRowAnimation:
toinsertRowsAtIndexPaths:withRowAnimation:
thetableviewtodirectittoadjustitspresentation.
Updatethecorrespondingdata-modelarraybyeitherdeletingthereferenceditemfromthearrayoraddinganitemtothearray.
WhentheuserswipesacrossarowtodisplaytheDeletebuttonforthatrow,thereisavariationinthecallingsequencediagrammedinFigure
7-1.Whentheuserswipesarowtodeleteit,thetableviewfirstcheckstoseeifitsdatasourcehasimplementedthe
method;tableView:commitEditingStyle:forRowAtIndexPath:
ifthatisso,itsends
tosetEditing:animated:
itselfandenterseditingmode.Inthis“swipetodelete”mode,thetableviewdoesnotdisplaytheeditingandreorderingcontrols.Becausethisisauser-drivenevent,italsobracketsthemessagestothedelegateinsideoftwoothermessages:
andtableView:willBeginEditingRowAtIndexPath:
.tableView:didEndEditingRowAtIndexPath:
Byimplementingthesemethods,thedelegatecanupdatetheappearanceofthetableviewappropriately.
Note:Thedatasourceshouldnotcall
setEditing:animated:fromwithinitsimplementationof
tableView:commitEditingStyle:forRowAtIndexPath:.
Ifforsomereasonitmust,itshouldinvokeitafteradelaybyusingthe
method.performSelector:withObject:afterDelay:
Althoughyoucanuseaninsertioncontrolasthetriggertoinsertanewrowinatableview,analternativeapproachistohaveanAdd(orplussign)buttoninthenavigationbar.Tappingthebuttonsendsan
actionmessagetotheviewcontroller,whichoverlaysthetableviewwithamodalviewforenteringthenewitem.Oncetheitemisentered,thecontrolleraddsittothedata-modelarrayandreloadsthetable.“An
ExampleofAddingaTable-ViewRow”discussesthisapproach.
AnExampleofDeletingaTable-ViewRow
Thissectiongivesaguidedtourthroughthepartsofaprojectthatworktogethertosetupatableviewforeditingmodeanddeleterowsfromit.Thisprojectusesthenavigationcontrollerandviewcontrollerarchitecturetomanageitstableviews.Inits
method,loadView
thecustomviewcontrollercreatesthetableviewandsetsitselftobethedatasourceanddelegate.ItalsosetstherightitemofthenavigationbartobethestandardEditbutton.
self.navigationItem.rightBarButtonItem=self.editButtonItem; |
tosetEditing:animated:
theviewcontrollerwhentapped;ittogglesthebuttontitle(betweenEditandDone)andtheBooleaneditingparameteronalternatingtaps.Initsimplementationofthemethod,asshowninListing
7-1,theviewcontrollerinvokesthesuperclassinvocationofthemethod,sendsthesamemessagetothetableview,andupdatestheenabledstateoftheotherbuttoninthenavigationbar(aplus-signbutton,foraddingitems).
Listing7-1Viewcontrollerrespondingto
setEditing:animated:
-(void)setEditing:(BOOL)editinganimated:(BOOL)animated{ |
[supersetEditing:editinganimated:animated]; |
[tableViewsetEditing:editinganimated:YES]; |
if(editing){ |
addButton.enabled=NO; |
}else{ |
addButton.enabled=YES; |
} |
} |
methodtableView:editingStyleForRowAtIndexPath:
(Listing7-2).
Listing7-2Customizingtheeditingstyleofrows
-(UITableViewCellEditingStyle)tableView:(UITableView*)tableVieweditingStyleForRowAtIndexPath:(NSIndexPath*)indexPath{ |
SimpleEditableListAppDelegate*controller=(SimpleEditableListAppDelegate*)[[UIApplicationsharedApplication]delegate]; |
if(indexPath.row==[controllercountOfList]-1){ |
returnUITableViewCellEditingStyleInsert; |
}else{ |
returnUITableViewCellEditingStyleDelete; |
} |
} |
messagetableView:commitEditingStyle:forRowAtIndexPath:
fromthetableview.AsshowninListing7-3,ithandlesthismessagebyremovingtheitemcorrespondingtotherowfromamodelarray
andsending
todeleteRowsAtIndexPaths:withRowAnimation:
thetableview.
Listing7-3Updatingthedata-modelarrayanddeletingtherow
-(void)tableView:(UITableView*)tableViewcommitEditingStyle:(UITableViewCellEditingStyle)editingStyleforRowAtIndexPath:(NSIndexPath*)indexPath{ |
//Ifrowisdeleted,removeitfromthelist. |
if(editingStyle==UITableViewCellEditingStyleDelete){ |
SimpleEditableListAppDelegate*controller=(SimpleEditableListAppDelegate*)[[UIApplicationsharedApplication]delegate]; |
[controllerremoveObjectFromListAtIndex:indexPath.row]; |
[tableViewdeleteRowsAtIndexPaths:[NSArrayarrayWithObject:indexPath]withRowAnimation:UITableViewRowAnimationFade]; |
} |
} |
AnExampleofAddingaTable-ViewRow
Thissectionshowsprojectcodethatinsertsarowinatableview.Insteadofusingtheinsertioncontrolasthetriggerforinsertingarow,itusesanAddbutton(visuallyaplussign)inthenavigationbarabovethetableview.Thiscodealsoisbasedonthenavigationcontrollerandviewcontrollerarchitecture.Inits
methodloadView
implementation,theviewcontrollerassignstheAddbuttonastheright-sideitemofthenavigationbarusingthecodeshowninListing7-4.
Listing7-4AddinganAddbuttontothenavigationbar
addButton=[[UIBarButtonItemalloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAddtarget:selfaction:@selector(addItem:)]; |
self.navigationItem.rightBarButtonItem=addButton; |
button,the
addItem:messageissenttothetarget(theviewcontroller).ItrespondsasshowninListing
7-5.Itcreatesanavigationcontrollerwithasingleviewcontrollerwhoseviewisputonscreenmodally—itanimatesupwardtooverlaythetableview.The
methodpresentModalViewController:animated:
todothis.
Listing7-5RespondingtoatapontheAddbutton
-(void)addItem:sender{ |
if(itemInputController==nil){ |
itemInputController=[[ItemInputControlleralloc]init]; |
} |
UINavigationController*navigationController=[[UINavigationControlleralloc]initWithRootViewController:itemInputController]; |
[[selfnavigationController]presentModalViewController:navigationControlleranimated:YES]; |
[navigationControllerrelease]; |
} |
save:action
messagetoitstarget:theviewcontrollerforthemodalview.AsshowninListing7-6,theviewcontrollerextractsthestringvalue
fromthetextfieldandupdatestheapplication’sdata-modelarraywithit.
Listing7-6Addingthenewitemtothedata-modelarray
-(void)save:sender{ |
UITextField*textField=[(EditableTableViewTextField*)[tableViewcellForRowAtIndexPath:[NSIndexPathindexPathForRow:0inSection:0]]textField]; |
SimpleEditableListAppDelegate*controller=(SimpleEditableListAppDelegate*)[[UIApplicationsharedApplication]delegate]; |
NSString*newItem=textField.text; |
if(newItem!=nil){ |
[controllerinsertObject:newIteminListAtIndex:[controllercountOfList]]; |
} |
[selfdismissModalViewControllerAnimated:YES]; |
} |
BatchInsertion,Deletion,andReloadingofRowsandSections
TheclassUITableView
allowsyoutoinsert,delete,andreloadagroupofrowsorsectionsatonetime,animatingtheoperationssimultaneouslyinspecifiedways.TheeightmethodsshowninListing
7-7pertaintobatchinsertionanddeletion.Notethatyoucancalltheseinsertionanddeletionmethodsoutsideofananimationblock(asyoudointhedatasourcemethod
astableView:commitEditingStyle:forRowAtIndexPath:
discussedin“Inserting
andDeletingRowsinEditingMode”).
Listing7-7Batchinsertionanddeletionmethods
-(void)beginUpdates; |
-(void)endUpdates; |
-(void)insertSections:(NSIndexSet*)sectionswithRowAnimation:(UITableViewRowAnimation)animation; |
-(void)deleteSections:(NSIndexSet*)sectionswithRowAnimation:(UITableViewRowAnimation)animation; |
-(void)reloadSections:(NSIndexSet*)sectionswithRowAnimation:(UITableViewRowAnimation)animation; |
-(void)insertRowsAtIndexPaths:(NSArray*)indexPathswithRowAnimation:(UITableViewRowAnimation)animation; |
-(void)deleteRowsAtIndexPaths:(NSArray*)indexPathswithRowAnimation:(UITableViewRowAnimation)animation; |
-(void)reloadRowsAtIndexPaths:(NSArray*)indexPathswithRowAnimation:(UITableViewRowAnimation)animation; |
andreloadSections:withRowAnimation:
methods,reloadRowsAtIndexPaths:withRowAnimation:
whichwereintroducediniOS3.0,allowyoutorequestthetableviewtoreloadthedataforspecificsectionsandrowsinsteadofloadingtheentirevisibletableviewbycalling
.reloadData
Toanimateabatchinsertion,deletion,andreloadingofrowsandsections,callthecorrespondingmethodswithinananimationblockdefinedbysuccessivecallsto
andbeginUpdates
.endUpdates
Ifyoudon’tcalltheinsertion,deletion,andreloadingmethodswithinthisblock,rowandsectionindexesmaybeinvalid.Callsto
beginUpdatesand
endUpdatescan
benested;allindexesaretreatedasiftherewereonlytheouterupdateblock.
Attheconclusionofablock—thatis,after
endUpdatesreturns—thetableviewqueriesitsdata
sourceanddelegateasusualforrowandsectiondata.Thusthecollectionobjectsbackingthetableviewshouldbeupdatedtoreflecttheneworremovedrowsorsections.
AnExampleofBatchedInsertionandDeletionOperations
Toinsertanddeleteagroupofrowsandsectionsinatableview,firstpreparethearray(orarrays)thatarethesourceofdataforthesectionsandrows.Afterrowsandsectionsaredeletedandinserted,theresultingrowsandsectionsarepopulatedfromthisdatastore.
Next,callthe
method,beginUpdates
followedbyinvocationsof
,insertRowsAtIndexPaths:withRowAnimation:
,deleteRowsAtIndexPaths:withRowAnimation:
,insertSections:withRowAnimation:
or
.deleteSections:withRowAnimation:
Concludetheanimationblockbycalling
.ListingendUpdates
7-8illustratesthisprocedure.
Listing7-8Insertinganddeletingablockofrowsinatableview
-(IBAction)insertAndDeleteRows:(id)sender{ |
//originalrows:Arizona,California,Delaware,NewJersey,Washington |
[statesremoveObjectAtIndex:4];//Washington |
[statesremoveObjectAtIndex:2];//Delaware |
[statesinsertObject:@"Alaska"atIndex:0]; |
[statesinsertObject:@"Georgia"atIndex:3]; |
[statesinsertObject:@"Virginia"atIndex:5]; |
NSArray*deleteIndexPaths=[NSArrayarrayWithObjects: |
[NSIndexPathindexPathForRow:2inSection:0], |
[NSIndexPathindexPathForRow:4inSection:0], |
nil]; |
NSArray*insertIndexPaths=[NSArrayarrayWithObjects: |
[NSIndexPathindexPathForRow:0inSection:0], |
[NSIndexPathindexPathForRow:3inSection:0], |
[NSIndexPathindexPathForRow:5inSection:0], |
nil]; |
UITableView*tv=(UITableView*)self.view; |
[tvbeginUpdates]; |
[tvinsertRowsAtIndexPaths:insertIndexPathswithRowAnimation:UITableViewRowAnimationRight]; |
[tvdeleteRowsAtIndexPaths:deleteIndexPathswithRowAnimation:UITableViewRowAnimationFade]; |
[tvendUpdates]; |
//endingrows:Alaska,Arizona,California,Georgia,NewJersey,Virginia |
} |
ofOperationsandIndexPaths,”explainsparticularaspectsoftherow(orsection)insertionanddeletionbehavior.
OrderingofOperationsandIndexPaths
YoumighthavenoticedsomethinginthecodeshowninListing7-8thatseemspeculiar.Thecodecallsthe
methoddeleteRowsAtIndexPaths:withRowAnimation:
afteritcalls
.insertRowsAtIndexPaths:withRowAnimation:
However,thisisnottheorderinwhich
completesUITableView
theoperations.Itdefersanyinsertionsofrowsorsectionsuntilafterithashandledthedeletionsofrowsorsections.Thetableviewbehavesthesamewaywithreloadingmethodscalledinsideanupdateblock—thereloadtakesplacewithrespecttotheindexes
ofrowsandsectionsbeforetheanimationblockisexecuted.Thisbehaviorhappensregardlessoftheorderingoftheinsertion,deletion,andreloadingmethodcalls.
Deletionandreloadingoperationswithinananimationblockspecifywhichrowsandsectionsintheoriginaltableshouldberemovedorreloaded;insertionsspecifywhichrowsandsectionsshouldbeaddedtothe
resultingtable.Theindexpathsusedtoidentifysectionsandrowsfollowthismodel.Insertingorremovinganiteminamutablearray,ontheotherhand,mayaffectthearrayindexusedforthesuccessiveinsertionorremovaloperation;forexample,ifyou
insertanitematacertainindex,theindexesofallsubsequentitemsinthearrayareincremented.
Anexampleisusefulhere.Sayyouhaveatableviewwiththreesections,eachwiththreerows.Thenyouimplementthefollowinganimationblock:
Beginupdates.
Deleterowatindex1ofsectionatindex0.
Deletesectionatindex1.
Insertrowatindex1ofsectionatindex1.
Endupdates.
Figure7-2illustrateswhattakesplaceaftertheanimationblockconcludes.
Figure7-2Deletionofsectionandrowand
insertionofrow
相关文章推荐
- UITableView(Inserting and Deleting Rows and Sections)
- Calling sequence for inserting or deleting rows in a table view
- Swift UI学习之UITableView and protocol use
- UIKeyboard and UITableView
- Lerning Entity Framework 6 ------ Inserting, Querying, Updating, and Deleting Data
- Understanding Reload, Repaint, and Re-Layout for UITableView
- UITableView and presentViewController takes 2 clicks to display
- Chapter 8 UITableView and UITableViewController
- swift 学习笔记 UITableView (一)Table View Styles and Accessory Views
- 4.12 Deleting Cells and Sections from Table Views
- WWDC笔记:2011 Session 125 UITableView Changes, Tips and Tricks
- numberOfSectionsInTableView:,tableView:numberOfRowsInSecion:,tableView:cellForRowAtIndexPath:
- UITableView的reloadData方法,不执行cellForRow方法,但是执行了numberOfRows和heightForRow方法
- (三)UITabBar and UINavigationController基础教程之UITableView的插入删除移动
- UITableView: Display and hide cells as a dropdown list
- 史上最简洁的UITableView Sections 展示包含NSDicionary 的NSArray
- Delete a Row from UITableView and Model-View-Controller
- iOS UItableview加载图片的时候的优化之lazy(懒加载)模式and异步加载模式
- iOS Quick Tip – programmatically hiding sections of a UITableView with static cells
- Swift UI学习UITableView and protocol use