I have created a UICollectionView programmatically. Its cells also contain programmatically created UILabel, UIView and UIImageView. The view that contains this collection view has also been created programmatically. I've set its datasource and delegate to self. The userInteractionEnabled property of label, view and image view has also been set to false. The allowsMultipleSelection property of collection view is also set to true.
The problem is that the didSelectItemAtIndexPath function is called whenever I touch the cells. But didDeselectItemAtIndexPath function is never called. I tried to set the cell.selected property to true/false as required but no aid to my problem.
Please help!! I've spent many hours searching about it but no result!!
Thanks for you responses.
Well, both this functions are called according to UICollectionViewDelegate in object which conforms to it. I highly advertise you to check this points:
After creation your custom collectionView don't forget to set it delegate property.
Implement this methods in your delegate object. -collectionView:didSelectItemAtIndexPath: or -collectionView:didDeselectItemAtIndexPath: and put there simple NSLog() output or breakpoints
Don't forget to set up UICollectionView property allowsSelection to YES
Face the result
Important notes
1. If you call UICollectionView methods like -selectItemAtIndexPath:animated:scrollPosition: or -deselectItemAtIndexPath:animated: any of this action will not be triggered nor notification will be received. As you remember, the same as in UITableViewClass
2. UICollectionView property allowsMultiplySelection allows you to switch between collection cells states
3. It doesn't matter where you create you elements. It just need to be setup correctly.
Hope this may help you.
Related
I have 5 different types of custom cells. So I want to get different heights from the custom cells because I'm using these cells number of times based on my requirement. Is there any way to write a code which will calculate the height of .xib and will set the height of cell as the .xib height. And the height of cell should change based on the custom cell that I have choosen.
My question is similar to this question but I'm not getting the solution as they said here:
Change tableview row height based on multiple cell xib
If you are implementing the custom table cell from xib, You need to subclass the tablecell method. You can use awakeFromNib to customize your table cell!!!
To know the cell height, you need to over ride the layout subviews method, and you can get the cell height by the following code:
self.frame.size.height
You can add an observer to the frame in the layout subviews method, so that you can get a notification, whenever there is a change in the height!!!!
From Documentation:
Prepares the receiver for service after it has been loaded from an
Interface Builder archive, or nib file. The nib-loading infrastructure
sends an awakeFromNib message to each object recreated from a nib
archive, but only after all the objects in the archive have been
loaded and initialized. When an object receives an awakeFromNib
message, it is guaranteed to have all its outlet and action
connections already established. You must call the super
implementation of awakeFromNib to give parent classes the opportunity
to perform any additional initialization they require. Although the
default implementation of this method does nothing, many UIKit classes
provide non-empty implementations. You may call the super
implementation at any point during your own awakeFromNib method.
I am using XCode5 and iOS7.
Is it possible to embed a UICollectionView into a normal UIViewController class and have the UIViewController implement the methods?
Or do I need the UICollectionViewController?
Which methods are required at minimum?
Yes it is possible to implement UICollectionView without UICollectionViewController. CollectionViews are just like tableView.
As you probably already know, when you use a UITableView you have to set a data source and a delegate in order to provide the data to display and handle events (like row selection).
Similarly, when you use a UICollectionView you have to set a data source and a delegate as well. Their roles are the following:
1. The data source (UICollectionViewDataSource) returns information about the number of items in the collection view and their views.
2. The delegate (UICollectionViewDelegate) is notified when events happen such as cells being selected, highlighted, or removed.
And new to UICollectionView, you have a third protocol you must implement – a protocol specific to the layout manager you are using for the collection view.
You can use a UICollectionView, you'll need the UICollectionView to conform to the UICollectionViewDelegate and UICollectionViewDataSource protocols.
so you will need at a minimum;
numberOfSectionsInCollectionView, numberOfItemsInSection and you'll need to implement cellForItemAtIndexPath to create the cells. Obviously you'll also need to define the Cell
Answer is NO. UICollectionView is subclass of UIVIew and can be added to any view you wish.
Since UIVIewController has view property you can add UICollectionView to it using:
[self.view addSubview:self.collectionView];
Here is a great tutorial with sample project where you can see how to implement UICollectionView in your custom UIViewController subclass:
http://www.raywenderlich.com/22324/beginning-uicollectionview-in-ios-6-part-12
You don't need an UICollectionViewController. Just make sure, that your ViewController implements the UICollectionViewDelegate and UICollectionViewDataSource.
This example should help you with the topic UICollectionView:
http://adoptioncurve.net/archives/2012/09/a-simple-uicollectionview-tutorial/
I'm building a blog reader app with a list of post objects in an NSArray.
cell.postTitle.text=post.Title;
I'm trying to find out which post has been selected and then set the corresponding cell.postTitle.text to a lighter font.
Somehow I have to remember this state when the navigationcontroller segue back to the top level (and destroyed?).
Can anyone tell me the best way to do this? Each post object has a postID. Maybe I can store this in NSUserDefault, but the list of read postID might grow too big over time.
Also there is didSelectRowAtIndexPath but in this method, I can't access the cell properties directly right?
If you are using a UITableView to display your information you should use the delgate didSelectRowAtIndexPath.
In order to make this work with a custom interface (I assume you have), you should create your own custom cell, subclass UITableViewCell and create a controller and xib. You can then register your xib to the table and use that. Then you can call the needed attributes.
Somehow I have to remember this state when the navigationcontroller segue back to the top level (and destroyed?).
This is best handled by using a delegate method by creating a custom protocol:
https://developer.apple.com/library/ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/WorkingwithProtocols/WorkingwithProtocols.html
When your user clicks the cell, you would call a delegate method which could set the postID value back in the top controller.
Also there is didSelectRowAtIndexPath but in this method, I can't access the cell properties directly right?
Yes, you can get at the cell. Check out this question and answer:
How to reach the current selected cell in didSelectRowAtIndexPath?
Alternatively, if you want to get at the data you used to create the table cells in the first place, in your didSelectRowAtIndexPath method you can used the indexPath.row value to get the value from your array that is at that index position and pass that via a delegate method.
Found a solution.
Just add the postId of the selected post to an NSMutableArray in didSelectRowAtIndexPath. Then in cellForRowAtIndexPath, I check to make sure that the postID doesn't exist in my self.readPostID array.
If it does I set the font to Helvetica Light, else set it to Helvetica Bold.
First I had to make sure to [self.tableview reloadData] every time viewdidappear.
Second, I just save my NSMutableArray of readPostId to NSUserDefault everytime viewDidDisappear and reload the array in viewDidLoad.
Also I had to make sure that cell reuse doesn't affect the font. The else condition fixed that.
iOS Proficiency: Beginner
If I have a Xib with multiple fields that all need their own Picker View, what's an appropriate/canonical way to add multiple picker views on the page without getting the Design View all cluttered up?
1) Only add the PickerView programmatically and not via the XIB?
2) Use only 1 Picker object and populate it with different values based on the field
selection? (Possible memory benefits?)
3) Place the UIPickers on the View with a tiny height/width and then programmatically adjust height when necessary? Not even sure if the height is adjustable.
4)Combination of some of the above?
You can see in the image below, how cluttered it looks already even with just one picker view:
The view that you have with the text fields and picker views would lend itself to be part of a UITableView.
See the calendar app when you add an event.
You can set this up fairly easily by using a static UITableView.
I'm replying on my phone at the moment but will look for a tutorial if you would like.
If only one pickerView will be visible at once, then you should consider using only one pickerView and configure it's delegate/datasource so that you can give it a different datasource for each field.
Unless more than one is visible at once, there really isn't any reason to use more than one in your nib file. And even if you used more than one, you would still have to configure you delegate/datasource methods to handle each individual picker.
Hope that helps.
EDIT: It would be a little bit of work, but if you wanted the pickerView to animate in and out of the view whenever you need and if you wanted to clean your Xib up even more you could do the following:
Create a subview containing your pickerView
Set up a protocol on the subview to allow you to pass the selected value back to the view controller.
Set up your viewController to conform to the protocol on your picker subview.
Set the pickerView to be each textField's inputView.
Set the textField's delegate methods to configure the dataSource of your subview when editing begins.
By doing this, you have set your textField so that when it receives firstResponder that it will display the pickerView instead of a keyboard.
I'm stuck with the problem that I want to know in my UITableView if a specific UITableViewCell, let's say the first, is still visible or already off the visible area.
I would also be ok to know if the cell of interest is now beeing reused at an other indexPath of the table.
One of my - later and frustrated approaches - was to have a thread that knows the first cell object and frequently pings it to check if a value I did set in the cell changed. Obviously a not so good solution.
Andy ideas how to do this right?
Remember that UITableView is UIScrollView subclass and its delegate also confirms to UIScrollViewDelegate protocol as well.
So in your table delegate you can implement scrollViewDidScroll: method and check contentOffset - if it's more then first cell height then first cell is not visible. You can also get the array off all currently visible cells using -visibleCells method, but I think knowing contentOffset should be enough.