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];
}
}
Related
How do you exclude specific views from having a touch delay in a UIScrollView when delaysContentTouches property is set to YES?
Here's what works for me. Subclass UIScrollView, and implement only this method:
- (BOOL)touchesShouldCancelInContentView:(UIView *)view
{
NSLog(#"touchesShouldCancelInContentView");
if ([view isKindOfClass:[UIButton class]])
return NO;
else
return YES;
}
I'm trying to figure out how much of the scroll view inside my UIPageViewController has been scrolled. I have the following code in the viewLoad that access the UIScrollView from UIPageViewController.
for (UIView *view in self.pageViewController.view.subviews)
{
if ([view isKindOfClass:[UIScrollView class]])
{
thisControl = (UIScrollView *)view;
}
}
So once I have the UIScrollView, called thisControl I would like to print how much has been scrolled by doing something like this:
NSLog (#"Scroll: %f",thisControl.contentOffset.x);
The problem, is that I don't really know where to put this line, or how print continuously how much has been scrolled.
Any idea?
Set the delegate to that controller(myScroll.delegate = self;) and then add this method:
- (void) scrollViewDidScroll: (UIScrollView *) scrollView
{
CGFloat y = scrollView.contentOffset.y;
NSLog(#"%f",y);
// some stuff
}
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.
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.
In my app, i have table view in which i am reloading data based on Business logic so it was overlapping earlier then i write this piece of code to remove content before drawing:
for(UIView *view in cell.subviews){
if ([view isKindOfClass:[UIView class]]) {
[view removeFromSuperview];
}
}
And now its removing everything including cell separators. Any idea how to prevent it??
Thanks,
Remove subviews from [cell contentView]
If you don't know what are you doing, you should never add views or remove views from the cell directly. Use only contentView, backgroundView and selectedBackgroundView.
However, there is rarely a use case when you should remove all the views from a cell. Why don't you just create a new cell (or reuse one)? Or just set the hidden property to YES for the subviews?