On iOS, is there a way to search ONLY subviews wit

2019-02-25 18:01发布

问题:

Because right now, viewWithTag actually search for itself first, and then all subviews recursively down the whole subtree, for a view with that tag.

But what if I set the tags of the subviews to 100, 101, etc, and later on, look for tag 100, but the parent of this current view sets the current view's tag to 100? Then viewWithTag will return the current view instead of any subview.

It is also strange that if the code is

[fooView viewWithTag: 123]

why would the code want to search the subtree including fooView itself? It is like, the code doesn't know fooView good enough to want to search for it too. Or put it another way, fooView is told to search itself... which is strange. A view doesn't know itself? (need to do a search to look for itself?)

So is there a way to search for subviews and grand-subviews only (without searching for self)?

回答1:

Take advantage of the recursive nature of -viewWithTag:

- (UIView *)viewWithTagNotCountingSelf:(NSInteger)tag
{
    UIView *toReturn = nil;

    for (UIView *subView in self.subviews) {
        toReturn = [subView viewWithTag:tag];

        if (toReturn) {
            break;
        }
    }
    return toReturn;
}

Edit: this will drill down farther than "grand-subviews": it will get any view within the hierarchy that is not self. Also this is to be implemented in a category on UIView.



回答2:

After reviewing the documentation for -viewWithTag: and running a few tests, it appears the answer to OP's question is - This behavior is already provided.

Return Value

The view in the receiver’s hierarchy whose tag property matches the value in the tag parameter.

Discussion

This method searches the current view and all of its subviews for the specified view.

I am concluding this to mean that 'view' is also a 'subview', thus limiting the scope of the search.



回答3:

do this:

NSMutableArray *arrSameViewTag = [NSMutableArray array];
for(UIView *subview in [yourView subviews]) //your view to find subview
{
    if(subview.tag == 123) //specific tah here
    {
        [arrSameViewTag addObject:subview]; //view found add in array
    } 
}
NSlog(@"arrSameViewTag : %@",arrSameViewTag);

To find specific like UIButton or any UIElement then like this:

NSMutableArray *arrSameViewTag = [NSMutableArray array];
for(id *subview in [yourView subviews]) //your view to find subview
{
  if([subview isKindofClass[UIButton class]) //any UIElement of specific type here
  {
    UIButton *btn = (UIButton *)subview; //same UIElement mentioned for checking it
    if(btn.tag == 123) //specific tah here
    {
        [arrSameViewTag addObject:subview]; //view found add in array
    } 
  }
}
NSlog(@"arrSameViewTag : %@",arrSameViewTag)


回答4:

For 1 level:

UIView *view;
for (int i = 0; i < viewToSearch.subviews.count; i++){
    UIView *subview = viewToSearch.subviews[i];
    if (subview.tag == tagToSeach){
        view = subview;
        break;
    }
}

To search a view hierarchy with multiple levels:

__block UIView *view;
BOOL (^__block searchViewForTag)(UIView *,NSInteger) = ^(UIView *aView, NSInteger tag){
    for (UIView *subview in aView.subviews){
        if (subview.tag == tag){
            view = subview;
            return YES;
        }
        if (searchViewForTag(subview,tag)) return YES;
    }
    return NO;
};
NSInteger tagToSearchFor = 1;
searchViewForTag(viewToSearch,tagToSearchFor);

//Do something with view


回答5:

let result = view.subviews.filter{$0.tag == tag}.first