Is it possible - and how - to talk to any other visible UITableViewCell from within another cell inside a UITableView?
I have two kinds of cells, lets say blue and red ones. the distribution of the two kinds of cells inside the listview is randomly. the problem I need to solve is: I want to make all visible red cell communicate.
Thnx!
The easiest way to communicate without passing pointers, defining protocols and delegates is always NSNotification.
You can think of NSNotification as a kind of "switchboard" which allows you to pass custom messages across your app, without worrying about "connecting" all dots.
You post notifications with postNotification,
you must set observers and their target methods in the object in which you want to handle the notifications.
You could set different cells to different UITableViewCell derived classes, and post/receive notifications among them.
Remember to:
- remove observers before the object they contain gets deallocated (e.g. in viewWillDisappear for viewControllers, etc).
- don't add your observers twice.
Maybe for some cases it would be enough to use the simple
let selectedCell = tableView.cellForRowAtIndexPath(indexPath)
to solve the problem!
Related
Imagine this scenario:
I've 10 different and custom UITableViewCell: one with a textfield,
one with a button, one with some labels, one with a textview, one
with an imageView and so on.
I've a ViewController with a tableView where I wanna display these cells.
The number of cell displayed can vary based on some conditions (and also the height, the background color and other parameters)
The user can interact with these cells
What is the best way to design this in respect of the MVC and maintain the ViewController lightweight and maintainable as possible?
How to take advantage of Swift language in doing this?
Is there any famous and consolidate design pattern to apply?
i will try to share some of my experience:
Create separate custom UITableViewCelll as per requirement like : textfield, textview, imageview, label etc. this class must not dependent on data calculation it is only for cosmetics UI. that means there must not be any method like updateCellWithData:(someDATAObj). This logic must go in some cetegory as discussed below.
Register separate custom UITableViewCelll with your tableview.
Create separate class (NSObject) as datasource and delegate for your UITableView.
Use category to populate data in your custom UITableView Cell. some thing like updateCellWithData:(someDATAObj).
Use constant file for your constants like height for tableView Cell, reuse identifier names, notification name.
try with some code atleast, then we can help you with best.
I am wondering what exactly happens, when you dont use dequeueReusableCellWithIdentifier in the cellForRowAtIndexPath-method.
In one Project I am collaborating we have different types of custom UITableViewCells which all appear in one single tableview. So here we fill arrays with all TableCells that should be displayed. These arrays are not very big (10-15 Cells) so for us that way works even not using any identifiers for dequeueReusableCellWithIdentifier. The next question is how at all you could use identifiers resp. dequeueReusableCellWithIdentifier when using different Cells in one single section of an UITableView. Is someone here hwo can explain, what exactly happens in background? Regards Nils
The dequeueReusableCellWithIdentifier is something that reminds me of Flyweight pattern.
Since allocation and instantiation of a cell can be an expensive task, using this mechanism you have the opportunity to create only the first visible cells and later reuse them just changing their contents. Scrolling animation must be as fast as possible to give a good experience to the user.
Is it worth it? Yes and it basically comes for free, we just need to pay attention that some old data can be still present in a new visualization, the trick is to always implement the method -prepareForReuse() correctly, here, you can eventually wipe all displayed data before setting the new one.
If you want to use different cells in the same section is absolutely possible, also if they have different height. You just need to crate different cell identifiers, one for each cells and tie them somehow along with your data.
I usually map data to be displayed in struct (swift) or dictionaries along with a key for the cell identifier to be used.
If your type of cells are representing themselves while scrolling you should dequeue them.
I have a two-days-brain-breaking-question to all of you:
I integrated a menu in my application by using a UICollectionView (one line, horizontal scrolling, fixed number of 9 items). Every cell has an own tag and uses an own prototype cell with own identifier. During the cellForItemAtIndexPath I assign a prototype cell to every cell (the prototype cell contains the specific UIButton in the storyboard). If you click a cell (respective the UIButton) a popover should open (this is working quite well, because the popover is anchored to the collection view not to the cell - otherwise Xcode will give an error, because of an outlet bind to repeating content.). Now to the questions:
Dependently from the chosen value in the popover, the name (titleLable.text) of the button should change. I think, an IBOutlet is needed, but not usable, because of the possible (but not happened) multiple (re)use of the cell.
Some other action in the APP could happened randomly, that changes the label of the button. Therefore an IBOutlet is needed too, I think.
I tried to give the prototypes a specific tag, but this (in my opinion) could not be used, because I cannot assign the tags to an UIButton, during loading, because not all of the cells are visible and therefore not reachable in viedDidAppear...
Any help is appreciated. This is a new try for an old problem and the collectionView till yesterday looked quite promising. Any ideas to help? Thanks a lot. I canĀ“t give code, because 90% of the work are done in IB.
you can use NSNotificationCenter to send message from your UIPopoverController to a UICollectionViewCell.
Send and receive messages through NSNotificationCenter in Objective-C?
Just subclass UICollectionViewCell to MyCollectionViewCell and use your subclass in your UICollectionView.
At the -(void)initWithFrame:(CGRect)frame method of MyCollectionViewCell you should subscribe as an observer to NSNotificationCenter, and unsubscribe in dealloc.
Than all your cells may receive notification and react to it.
This is not an optimal way of receiving callbacks, but maybe the simplest.
I have PersonCell with xib and .h, .m files and person's characteristics. So, depending on PersonCell.state, I want to show different number and kind of characteristics.
I want to use a specific Parameterview with titleLabel and constantLabel, so i can add those parameterViews with for-in array. I can't use constraints in code, coz of cell reuse.
How to do that? I see only stupid way - add every characteristic view to PersonCell and depending on the state, show and hide them. But there are 50+ different characteristics.
You could try use a tableView instead of the array of views. For example, the PersonCell could have a tableView inside, where each cell contains a ParameterView.
From the array you already have, you could implement UITableViewDataSource in the PersonCell. I think this would be a pretty simple solution when the PersonCell depends so much on the state.
Let me know if you have questions or you need more specific information.
I noticed in using UITableView, UICollectionView, UIPickerView, UIScrollView, ..., and numerous other UIKit classes that the UIViewController containing the object instance often bears the role of DataSource and Delegate.
I understand from Apple's documentation what these data source and delegate methods are called, and how to implement them... for a single instance of each class.
My question is, how do you handle different instances in the same UIViewController? For example, if I have two UICollectionViews, or three UIPickerViews, ...., or fifty UIScrollViews? I can implement the data source method only once per UIViewController, but I somehow have to tell the program different instructions?
The only thing I can conceive is a gigantic switch statement or a bunch of cascading if-else if-else comparing the input to the delegate or data source method to each object instance in the UIViewController, which might get out of hand if there are many.
While we're used to using our view controller as the delegate, there's no need to do so. You can actually create NSObject subclasses that conform to the delegate protocol in question. You can then instantiate those objects and use them as the delegates of the UI objects (or whatever) as needed.
For example, consider a scene where I have two text fields, one which permits only numeric values, and one that does not accept numeric values. I can write a separate delegate object for each type of text field.
If implementing this programmatically, I would manually instantiate the two delegate objects, keep some strong references to them in my view controller, and then in viewDidLoad I can set each text field's delegate to be the appropriate delegate object.
If doing this in Interface Builder, you can actually drag an "Object" from the "Object Library" onto the scene (either in the bar above the scene or the document outline to the left of the scene):
You can then specify the class for this object:
Repeat this for all of your delegate objects:
And finally, you can go to your text field and specify the delegate by control dragging to the delegate object you added to the scene:
Doing it in Interface Builder means that it completely takes care of the instantiation of this delegate object for me and I have to do nothing in view controller's code.
Bottom line, if you want distinct behavior for a UI object, you can just instantiate a separate delegate object that manifests the desired behavior, and use that as the UI object's delegate. This pattern of instantiating separate delegate objects is common in iOS 7 custom transitions (where we have all sorts of delegate objects banging about), but can be used in this context, too.
BTW, you can obviously just subclass the UI control in question, too, and further encapsulate the logic there. That works equally well.
By creating referencing outlet for each controller,for example if you have two UITableView ,You can create outlet for each such as table1 and table2. To set number of rows in a section for these table ,you can code like follow
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == table1) {
return 10;
}
if (tableView == table2) {
return 5;
}
return 1;
}
You can create independent UIViews for each tableView or collection view with it's own .swift and .xib (and maybe if they are very similar you can reuse them). Doing that you will have the tableView and collecionView delegate methods in separated files and everything will be more clear. In your view controller you will just have to place the views, but you won't have any delegate methods there.
Well you are asking to differentiate the views with datasource & delegate in a smarter way. But you are overthinking this thing.
Everyone takes the different tableviews or pickers because they wan't be the same.
Otherwise they can be reused.
Now if they are going to be different from others then ultimately somewhere in your code you have to put the if...else or case statements. For example for tableview while setting the value of an UILabel or any value in your UITableViewCell.
If you are facing a such an issue that you have to put that many scrollviews or something in only one UIViewController then its an impossible situation if you are following the coding standards or may be your app design is faulty.