I'm trying to bringtofront my subview because the delete button keeps disappearing.
#implementation MyCell : UITableViewCell
- (void)layoutSubviews
{
[super layoutSubviews];
for (UIView *subview in self.subviews) {
for (UIView *subview2 in subview.subviews) {
NSLog(#"HERE!");
if ([NSStringFromClass([subview2 class]) isEqualToString:#"UITableViewCellDeleteConfirmationView"]) {
NSLog(#"got inside the if!");
[subview2 sendSubviewToBack:subview];
[subview bringSubviewToFront:subview2];
[self.superview bringSubviewToFront:subview2];
}
}
}
}
#end
I subclassed UITableViewCell. Both the NSLogs are printing so I know it's getting in there, but I've tried all 3 of these methods to put the view in front. Any ideas why this wouldn't be working?
subview2 is a subview of subview, which is a subview of self. The receiver of the sendSubviewToBack: or bringSubviewToFront: message must be the superview of the view given as argument. Therefore only the second one of the calls you make is valid. The correct calls would be
[self.superview bringSubviewToFront:self];
[self bringSubviewToFront:subview];
[subview bringSubviewToFront:subview2];
(And the same for sendSubviewToBack:.)
As for your actual problem, I can't figure out the view hierarchy you are using from the code posted, but it seems that it is incorrect. You should probably not have your custom views as direct subviews of self, but rather as subviews of self.contentView (as per Apple's documentation).
Related
I am creating a UIView every time I click on the button, but the problem is all other views are not getting deleted.
It's increasing the memory of the application
You can set a tag for UIView objects.
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
view.tag = 2016;
[self addSubview:view];
Then, you can remove it later using this code :
UIView *view = [self viewWithTag:2016];
[view removeFromSuperview];
You can also keep a reference to an UIView object with a property.
#property (nonatomic, strong) UIView *view;
So you can remove it very easy.
Try this:
Assign a tag(may be 100) to the button.
NSArray *subviews = self.view.subviews;
for(UIView *subview in subviews) {
if(subview.tag != 100) {
[view removeFromSuperview];
}
}
-removeFromSuperview method release's memory after it is called only in case if your view is not retained by anything else
e.g.
Simply removing view from superview may not be sufficient to deallocate it can have view that has an outlet connection & declared property for it with retain or strong attribute, so in this case it will be retained by the controller while it is being loaded from nib file and you may need to release that view.
[yourView removeFromSuperview];
self.yourView = nil;
I have a bunch of UIViews that I subclassed that I have been adding to self.view e.g.:
MySpecialView *myView = [[MySpecialView alloc] init];
[self.view addSubview:myView];
Now I want to remove them all from self.view but only those custom ones. I don't want to remove any of the others (I have some other views with options in them etc). Is there anyway of doing this at all? Can I loop through all the subviews and check their type? Any pointers on this would be great! Thanks!
Try a loop like this
for (UIView *view in self.view.subviews)
{
if ([view isKindOfClass:[MySpecialView class]])
[view removeFromSuperview];
}
This simply iterates through all of the subviews and removes any that are of class MySpecialView.
Swift way
for subview in self.view.subviews {
if subview.isKindOfClass(MyClass) {
// Is that class!
} else if subview.isMemberOfClass(MyClass) {
// Is that class or a subclass of that class!
}
}
I've UITableViewController with UISearchBar in headerView.
When typing some string to search the status bar doesn't show correctly.
All delegates and outlets are in place.
UPDATE:
Temporary fix which personally I don't like, but it still work (animation movement looks bad anyway):
- (void)resizeSeachBarBackground
{
for (UIView *view in self.searchDisplayController.searchBar.subviews)
{
if ([view respondsToSelector:#selector(subviews)])
{
for (UIView *view2 in view.subviews)
{
if ([view2 isKindOfClass:NSClassFromString(#"UISearchBarBackground")])
{
id UISearchBarBackground = view2;
if ([UISearchBarBackground respondsToSelector:#selector(frame)])
{
[UISearchBarBackground setFrame:CGRectMake(0, -20, CGRectGetWidth([UIScreen mainScreen].bounds), 64.0)];
break;
}
}
}
}
}
}
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
if (!self.navigationController.navigationBarHidden)
[self.navigationController setNavigationBarHidden:true animated:false];
[self resizeSeachBarBackground];
..
..
..
}
After hours of trying, I delete the previous code, deleted the search bar and outlets and connected all over again.
Instead of deleting the same, Disable the auto layout inside interface builder and then enable the same and do the proper connection of auto layout.
Putting the following line in the viewDidLoad fixed to it:
self.edgesForExtendedLayout = UIRectEdgeNone;
So I have a UIScrollView that is populated with a series of MyCustomViews that are subclasses of a standard UIView. In the delegate callback "scrollViewDidScroll I am trying to loop through all the subviews and call a specific function on them but I don't think the typecasting is working. Here is my code below:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
for(UIView *subView in [scrollView subviews){
MyCustomView *customView = (MyCustomView *)subView;
[customView myMethod];
}
}
When I call "myMethod" on customView, the program crashes saying an unrecognized selector was sent to instance. I believe that my type-casting is the issue as the method myMethod works in other situations. So how do I remedy this situation?
Solution 1:
If you do the following, you don't even need to cast your object to MyCustomView *. It can be of any type, e.g. UIView.
if([subView respondsToSelector:#selector(myMethod)]) {
[subView performSelector:#selector(myMethod)];
}
Solution 2:
You can check the object type before doing the cast.
if([subView isKindOfClass:[MyCustomView class]]) {
MyCustomView *customView = (MyCustomView *)subView;
[customView myMethod];
}
For "catch" this issue, use
if([customView respondsToSelector:#selector(myMethod)]){
[customView myMethod];
}
and with this, the app don't crash.
Also in your for use for(MyCustomView* customView in [scrollView subviews]){
In my app I need to call some UIViews more than once. But in one of my method, i've a code like :
[self addSubview:UIImageView];
But i've read that addsubview method must be call once. So, to let the code how is it, how could I check if it's already on subview ? Like :
if ([UIImageView isOnSubview] == NO)
{
[self addSubview:UIImageView];
}
Because I don't find any method to check this :/
Thank you !
You are probably looking for UIView's -(BOOL)isDescendantOfView:(UIView *)view; taken in UIView class reference.
use this one
for (UIView *subview in [self subviews])
{
NSLog(#"%#", subview);
// ---------- remember one thing there should be one imageview ------
if(![subview isKindOfClass:[UIImageView class]])
{
[self addSubview:UIImageView];
}
}