I'm trying to implement a subclass of UICollectionViewCell.
I'm getting an array of custom views, let's call it views passed from one object to another, also with an array called views. They are of type CustomView.
The UICollectionViewCell subclass has one property called view of type CustomView.
In CellForItemAt..., I'm trying to set the cell's view property from an array of CustomViews like this:
let customView = array[indexPath.row]
cell.view = customView
However, when I do this, the cells don't show properly; they're empty, and just grey shapes on the screen.
But, when I explicitly set the properties of the cell's CustomView subview, it shows how I'd like it to.
Is there a way to do a layout pass on the cell? Or do you have to just explicitly set properties in UICollectionViewCells instead of just passing in a pre-configured view?
The code is proprietary, so I have to be cryptic, but please let me know if I can clarify
Edit: Please see the comments in the accepted answer for further explanation
You should be adding constraints, or else you are getting the default auto resizing mask constraints. Call cell.setNeedsLayout() to force auto layout to recalculate before the next draw after you assing the voew.
Related
This question already has answers here:
Programmatically send to front/back elements created from interface builder
(2 answers)
Closed 10 days ago.
I am using a .xib for my cell in a table view. Inside the .xib, is another view (cellBackgroundView), and a button. When I run the app, and click the button, it does not respond at all. Instead, it calls the tableView's didSelectedRowAtIndexPath method which brings another view controller.
Using Xcode's Debug View Hierarchy, I discovered that I have a view overlaying the all the buttons (see pic attached: this overlaying view is highlighted). This view (called backgroundView) that is overlaying my button is a View, within a view. I have a feeling when you place a view in a view, and put a button in the initial view, the button isn't called because its below the view hierarchy.
How do I fix this issue? Is there a way to move background view to the back of the view heirarchy so that the buttons will be responsive?
Debug View hierarchy:
Structure of .xib
Two things that you could check
1) Do you have a delegate method for cell height and is the height returned correct? Unless you have Clip Subviews on for the UITableViewCell, the contents of the cell can be visible outside it's frame, but the parts that are outside the cell's frame are not registering user interactions.
2) Is some other view element higher in the hierarchy (lower in the XCode listing you posted) overlapping the button? iOS Simulators Debug -> Color Blended Layers can help spotting this.
Edit:
If I interpret the added screenshots correctly, you probably have the issue mentioned in the option 1) above. If the other elements showing in the screenshot are those listed as subviews of the Cell Background View they are mostly outside the parent view's frame and thus don't receive touch events. If the background view's frame is correct, then you might want to move the other elements as children for Feed Cell directly.
Also, the element listing suggests that you are using plain UIView as the parent element. I don't know the inner workings of your application, but if you only use this view in a UITableViewCell you might want to consider making the parent view a Table View Cell in the xib. This will reduce some bloat and allow you to configure some properties for the cell in the xib.
Maybe you forgot assign your Button to code
I assume Feed Cell is a subclass of UITableViewCell, and cellBackgroundView is the property contentView of this cell.
If so, the cells property backgroundView should be behind your cellBackgroundView (the docs say: UITableViewCell adds the background view as a subview behind all other views and uses its current frame location.).
You could set the cells property backgroundView = nil, and see whether it is still there in the view hierarchy. If so, you do add a custom backgroundView on top of the other cells views somewhere.
To check this, you could read out the subview hierarchy of your cell in your method tableView:cellForRowAtIndexPath: with something like NSArray *svs = cell.subviews; (assuming cell is the tableViewCell) and set a breakpoint behind this statement.
svs usually contains first the UITableViewCellContentView, and above it the _UITableViewCellSeparatorView. The cells backGroundView will not be shown. You could check there your view hierarchy.
If by chance there is a custom backgroundView on top, you could - as a workaround, not a solution - bring the contentView to the front by sending to the cell bringSubviewToFront: with the contentView as argument. Then the button should respond.
In your Structure of Xib Place your button below the view that is first the view is added to superView then the Button, then your button will work.
or you can code
-(void)viewDidLayoutSubviews{
[self.view insertSubview:yourButton aboveSubview:cellBackgroundView];
}
Hope it will help.
Do you add an UIButton by code?
If so you should ensure you addSubview: into cell.contentView and not into cell.
Also you could try to apply CellBackground class to a view inside contentView, not directly to contentView.
you can use this method.
[cell.contentView bringSubviewToFront:yourButton];
after that if you want to back in background then tou can use sendSubviewToBack: method .
After adding this methods your button is not responding set the userIntractionEable of button's superview.
I have a UITableViewCell. How should I add a subview to it? I have seen many example to add subview to the contentView, but why not directly to the cell?
You can do it, but If you want to customize cells by adding custom view, you should add them to the contentView in order to get them animated along the table animations
When you add a custom view to contentView or assigning to contentView handles framing resizing part ,animation part and when editing mode is ON (tableView.editing = YES;) tableview tries to operate with views of itself meaning contentView, accessoryView. So when you want to add something to the table view and let control be given to tableView go for contentView
The main problem is that it does not respect the design done in the storyboard. The coordinates of the image and the labels are as a basic cell. Note that such attributes are observed as the alignment of the label.
The button that has been added, is below the label.
I've definitely seen this issue before and I believe it is because imageView and textLabel are properties of UITableViewCell and the default implementation of layoutSubviews is overriding your storyboard's layout with UITableViewCell's defaults.
Try overriding layoutSubviews, or provide your own image and label properties (named differently from UITableViewCell's, ie: myImageView and myTextLabel).
I have a table view and its every cell`s width say 1024px , so my requirement is after clicking a cell tableview's width will change logically. And my table view is bit complex.
Every cell contains a custom view which is defined in another class. Please help me..
I do not believe there is a way to modify a single cell's width without changing the width of the table view, only height using tableView:heightForRowAtIndexPath:.
Therefore, you might want to change the width of the custom view inside your cell.
First, to get the cell in question, call cellForRowAtIndexPath: on your table view wherever you need (if you want to change the width on tap, that would probably be in your tableView:didSelectRowAtIndexPath:).
To access your custom view, you may give your custom view a tag number inside of the UITableViewCell by setting the custom view's tag property when creating the cell or in the storyboard. Then, call viewWithTag: on the UITableViewCell instance to get the custom view, and modify the width of its frame property.
Another, perhaps more suitable option would be to use a custom UITableViewCell class for your table view cells. That would mean subclassing UITableViewCell and creating a property for your custom view, which would allow you to access the custom subview through the getter and then change its frame property.
If you need the width of the custom view's container to change (which is currently your cell), simply embed the custom view inside a UIView and modify the UIView's width rather than the UITableViewCell's instance in the same manner described above.
In iOS6, I cannot seem to get the width of the cell in cellForRowAtIndexPath for the grouped table style. Logging either the frame or the bounds for either the cell or its contentview returns 320 - even on iPad. I need to determine the cell width programmatically for any device as I need to calculate text sizes. Any advice in getting the correct cell width for a grouped tableview in cellForRowAtIndexpath would be appreciated please
The method you're using is the wrong place to calculate any kind of view-related constraints. The -tableView:cellForRowAtIndexPath: method is part of the table view's data source, not its delegate. You cannot rely on the frame or anything else here to be meaningful, it's meant as the place to configure the cell's /data/.
If you need to make calculations to view frames and such, and you're not using a custom subclass of UITableViewCell (i.e., you're just adding views to a default instance of UITableViewCell or configuring stock views), you would set up any frame-related / view specific attributes in the /delegate/ callback -tableView:willDisplayCell:forRowAtIndexPath: method. This is the place to configure any of the visible/view-related properties of your cell, and you will now have accurate layout information for the cell (its bounds will be correct, any layout/configuration of internal views will be complete, etc.).
If you have a custom subclass already, you can either do your view related property configuration in the delegate callback above, or you can do it in UIView's -layoutSubviews method, depending on your exact needs. For more information, see the documentation for -tableView:willDisplayCell:forRowAtIndexPath:.