UICollectionView, Cell selection not working, cell scrolls fine - ios

So I have a uicollectionview, which resides inside a view controller, in this VC I have some buttons and other controls, and I load data into the CollectionView, I cannot detect the click on the collectionview, but it responds to scrolls fine.
All I can think of is that sometimes I enable userinteraction on all subviews in my view ( including the collectionview) , and this works, in the sense that no controls work, and then based on another condition I enable activity.
this is an example of the code
if (_isMenuVisible) {
for (UIView *subview in [self.actualView subviews]) {
if([subview isMemberOfClass:[UIButton class]] || [subview isMemberOfClass:[UILabel class]] || [subview isMemberOfClass:[UIView class]]) {
subview.userInteractionEnabled = _isMenuVisible;
}
else {
subview.userInteractionEnabled = !_isMenuVisible;
}
}
}
else {
for (UIView *subview in [self.actualView subviews]) {
subview.userInteractionEnabled = !_isMenuVisible;
}
}
Could this affect the behavior?

Make sure your ViewController adopts the UICollectionViewDelegate protocol. Then, as mentioned above, simply override the collectionView:didSelectItemAtIndexPath: to decide what you want to do when a certain cell is clicked.
Use the indexPath to determine the row or section of the cell by accessing its row or section property.

Related

Remove Subview from Superview

I am really stuck in this issue for quite a long time
I am trying to add a UIControl (which is a UIView in the end) to a UITableViewCell that i have subclasses in my own class (i made a custom cell)
on swipe, i create my UIControl class and add it to myself (the cell), so far so good. Here is the code
[self addSubview:_statusView];
However, i am adding a target action to my UIControl in the custom cell, so that the cell can handle when the UIControl says that he has recognized a touchDownEvent.
[self.statusView addTarget:self action:#selector(resetAll:) forControlEvents:UIControlEventTouchDown];
And here is what i want to do in the action, I want to remove that UIControl from self.subviews (the cell's subviews), so i set the action method to be like this
- (void)resetAll:(id)sender
{
for (UIView *view in self.subviews) {
if ([view isKindOfClass:[StatusView class]]) {
[view removeFromSuperview];
}
}
}
Can someone point out whats wrong in this code? because i can't really figure out why the view that gets added to the cell does't get removed. It seem to me the the subviews property doesn't ever contain my UIControl that i add.
- (void)resetAll:(id)sender
{
for (UIView *view in self.view.subviews) {
if ([view isKindOfClass:[StatusView class]]) {
[view removeFromSuperview];
}
}
}
or
- (void)resetAll:(id)sender
{
[sender removeFromSuperview];
}
UITableViewCell internally does some manipulations with its view hierarchy. You should add subviews not to the cell itself, but to its contentView, as stated in the docs:
If you want to go beyond the predefined styles, you can add subviews
to the contentView property of the cell.
So you have to replace
[self addSubview:_statusView];
with
[self.contentView addSubview:_statusView];
And then iterate on subviews of the contentView:
for (UIView *view in self.contentView.subviews) {
if ([view isKindOfClass:[StatusView class]]) {
[view removeFromSuperview];
}
}

No way to access UICollectionView supplementary views from view controller?

I have UICollectionView with a series of cells, and for each cell, some hidden annotations. The annotations are only meant to be shown when the the associated item is selected. So I added the following chunk of code to my controller's collectionView:didSelectItemAtIndexPath: method:
WESpan *span = self.selectedSpan;
for (UIView *view in self.collectionView.subviews) {
if ([view isKindOfClass: [AnchorCell class]]) {
view.hidden = ((AnchorCell*)view).anchor.span != span;
}
}
This works... but it seems ugly to me that I have to do the loop over all subviews, doing an isKindOfClass: check. Is there not a better way to do this? Something more idiomatic?
I wish there was an analog to the cellForItemAtIndexPath: method, so I could fetch just the ones correlated with the appropriate index and hide/unhide them.
collectionView:viewForSupplementaryElementOfKind:atIndexPath: ?
If you want to update a value in the supplementaryView you could always update your model and then reload the section of the collectionView.
[collectionView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section]];

UITableView in self.view

I'm trying to customize all my tableViews using this code but Xcode is giving me an error.
I have 2 tableViews and I need to find the tableView != self.tableView.
How can I do that?
for(UITableView *tableView in [self.view subviews]) {
if (![tableView isEqual:self.tableView]) {
tableView.separatorInset = UIEdgeInsetsMake(0, 58, 0, 0);
}
}
You need to use like below
for(UIView * view in [self.view subviews]) {
if ([view isKindOfClass:[UITableView class]]) {
UITableView * tblView = (UITableView *) view;
tblView.separatorInset = UIEdgeInsetsMake(0, 58, 0, 0);
}
}
I hope it helps you.
I suspect the error you are getting is something to do with the fact you are assuming every View you are getting back from subviews you are passing into a UITableView in UITableView *tableView in [self.view subviews] but not every view that is returned is going to be a UITableView and it is bad practice to assume that they will be. A good idea would be to change the UITableView to UIView because most if not all UI elements are subclassed from UIView. Once you have done that you will need to check that it is an instance of UITableView and if it is you can start casting view to a UITableView. See the revised code below for a better understanding.
// the issue in your code is that you are getting views back and you are assuming it is
// a UITableView (So I bet that the error is something do with this)
for(UIView *view in [[self view] subviews]) {
// Then we will want to check that it is an instance UITableView
// because not everything will be, the initial View will not be
// an instance of UITableView
if([view isKindOfClass:[UITableView class]]) {
UITableView *tb = view
// Right so we know we have a UITableView
// Now we want to check that it not equal to self.tableView as your code
// indicates you want
if(![tb sEqual:[self tableView]]) {
tb.separatorInset = UIEdgeInsetsMake(0, 58, 0, 0);
}
}
}
UPDATE
Thank you for providing the error
-[UIView setSeparatorInset:]: unrecognized selector sent to instance
The reason for this is because you will be getting a UIView returned in your for loop this is way we have the check to make sure that the view returned is of class UITableView and if it is we start casting to it.

UIButton is not enabling when all UITextFields are filled in

I am working on an iOS application where a button is enabled only after all UITextFields that are filled in (i.e. have at least one character inside each one). Each UITextField is in a custom UITableViewCell inside of a UITableView. Once the user has entered a value in each UITextField, I need the button to be enabled. Inside my viewDidLoad method, I disable the button as follows:
[_doneButton setEnabled:NO];
and then I have the following method:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
for (int i = 0; i < [self.table numberOfSections]; i++) {
NSInteger rows = [self.table numberOfRowsInSection:i];
for (int row = 0; row < rows; row++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:i];
SimpleTableCell *cell = (SimpleTableCell *)[self.table cellForRowAtIndexPath:indexPath];
for (UIView *subView in cell.subviews) {
if ([subView isKindOfClass:[UITextField class]]) {
//Does not come to this point
UITextField *txtField = (UITextField *)subView;
if([[txtField text] length] > 0) {
//Enable button and bold title
[_doneButton setEnabled:YES];
[_doneButton.titleLabel setFont:[UIFont boldSystemFontOfSize:28]];
}
else {
[_doneButton setEnabled:NO];
}
}
}
}
}
return YES;
}
Unfortunately, my code does not get into the "if" clause where I check to see if the custom cell has a subView of type UITextField, and because of that, the button is never enabled. For the record, "SimpleTableCell" is the name of my custom UITableViewCell class that I've created. My code appears to be correct, but I can't figure out why it is not functioning correctly. Can anyone see what it is I'm doing wrong?
I think I would go about this in a completely different way. I would create a mutable dictionary to hold the strings in the various text fields. Give the text fields tags, and use the tags (converted to NSNumbers) as the keys in the dictionary. Implement textFieldDidEndEditing:, and in that method get the string, check that it's not an empty string, and if not, do setObject:forKey: on the dictionary. After you set the value, check the count of the dictionary's allKeys property, and if it equals the number of text fields you have, enable the button.
That's because the only logical subview of the cell is an UIView containing all the items of the cell. It's property is "contentView".
The content view of a UITableViewCell object is the default superview for content displayed by the cell. If you want to customize cells by simply adding additional views, you should add them to the content view so they will be positioned appropriately as the cell transitions into and out of editing mode.
More information about it here: https://developer.apple.com/library/ios/documentation/uikit/reference/UITableViewCell_Class/Reference/Reference.html#//apple_ref/occ/instp/UITableViewCell/contentView
Have you set the UITextField's delegate? If that method is not getting called at all, that is the problem.

Getting index path of the table

I am using group of buttons with different images and tableview with custom cell in my project.every cell having group of components (like imageview,button,label,slider) when pressing each button one cell will be added.
My button image and also added to imageview of the cell.
How can i get the index of each cell when pressing the button again.
cell will be added when i press the button at first time.
when pressing second time i want to increment the label value inside the cell.so i need the indexpath to cell the cell from the tableview.
I'm not sure exactly what you're looking for, maybe you can clarify what you're trying to do.
The method indexPathForCell: is a UITableView method that gives you the index of a certain cell.
Clarify your question a bit and maybe we can help more.
You can call button touch event to get the cell of uitableview -
UIView *cellView = (UIVIew *)[button superview];
UITableViewCell *cell = (UITableViewCell *)[cellView superview];
NSIndexPath *indexPath = [self.tableview indexPathForCell:cell];
Without knowing the structure of your cells, table, or anything like that. this code will work.
-(NSIndexPath *) pathForButton:(UIbutton *) b {
UITableView *tv = nil;
UIView *superView = [b superview];
UIView *cell;
while(superview != nil && ![superview isKindOfClass:[UITableView class]]){
cell = superview;
superview = [superview superview];
}
if(superview != nil && cell != nil){
tv = (UITableView*)superview;
return [tv indexPathForCell:cell];
}
return nil;
}

Resources