1

In a view controller in a storyboard I have a simple view which has a subview image with tag 0 and a subview label with tag 1.

I'm trying to get the image like this:

UIImageView *myImage = (UIImageView*)[myView viewWithTag:0];

But when I do this:

myImage.highlighted = YES;

I get this:

-[UIView setHighlighted:]: unrecognized selector sent to instance

It is clearly a UIImageView in the storyboard. Why would this cast not work?

soleil
  • 12,133
  • 33
  • 112
  • 183

1 Answers1

1

Because of [myView viewWithTag:0] which is the tag number for the main view as well

Solution:

  • Give your UIImageView object a tag of, say, 100
  • Access it now as (UIImageView*)[myView viewWithTag:100]
staticVoidMan
  • 19,275
  • 6
  • 69
  • 98
  • This does fix it, but I don't understand why the 0 matters, since these are subviews. – soleil May 28 '14 at 20:54
  • It isn't looking only at subviews for the tag. – RegularExpression May 28 '14 at 20:58
  • @soleil Every view has a default tag of 0. And `viewWithTag:` starts with the receiver. So if the view you call it on has a matching tag, it will be returned. – rmaddy May 28 '14 at 20:58
  • ok, but what is the purpose of starting with the receiver? I mean, why would they design the API that way? – soleil May 28 '14 at 21:00
  • @soleil : well... when you do `[abcView viewWithTag:idx]`, it returns a **reference** to a view in `abcView` whose tag is `idx`. If `abcView`'s tag is `idx` then it returns a reference to itself. If not and suppose multiple `subview`s have the same `idx` tag number then the topmost view in `abcView`s hierarchy (_whose tag is `idx`_) is returned. Now... why it starts with `abcView` itself is something that I've not thought about but it seems like an interesting question. – staticVoidMan May 28 '14 at 21:04
  • @soleil A better question is "why shouldn't it start with the receiver"? It makes more sense as long as you use proper tags. – rmaddy May 28 '14 at 21:22
  • @rmaddy because if I ask you for your child named "Steve", I don't expect you to give me yourself if your name happens to be Steve. – soleil May 28 '14 at 21:27
  • @soleil The method is named `viewWithTag:`, not `subviewWithTag:`. – rmaddy May 28 '14 at 21:30
  • @soleil : that analogy is a little presumptuous as the objective-c equivalent would be `[steve whoIs:@"steve"]` and well... you know compilers \*sigh\* ...still evolving. But anyways... when you do `[abcView viewWithTag:idx]`, you're sending the `abcView` object a message to return a view whose tag is `idx`. So, technically, `abcView` is not the `UIView` but the class **that** contains the `UIView` (***which**, as per my observations, is often named `view`*) **that** contains the `subview`s. (_I may be wrong on this but this is what's on the top of my head right now_) – staticVoidMan May 28 '14 at 21:52
  • I'm still not convinced. Under this logic [someView subviews] should return itself as part of the array. – soleil May 28 '14 at 22:06
  • @soleil : well, the [description for `-viewWithTag`](https://developer.apple.com/library/ios/documentation/uikit/reference/uiview_class/uiview/uiview.html) states `This method searches the current view and all of its subviews for the specified view.` so. I guess... that's that. It's Apple's implementation of this method. – staticVoidMan May 28 '14 at 22:20
  • Yeah, I just don't understand why they did it that way. If I wanted the parent view, I could just ask for it, or check its tag. – soleil May 28 '14 at 22:21
  • @soleil : yeah, beats me. there may be some stupid reason. – staticVoidMan May 28 '14 at 22:25
  • 1
    @soleil : [similar question](http://stackoverflow.com/q/12225184/2857130) -- No reason provided but a manual workaround can be seen in the accepted answer which is basically a category method on `UIView` named `-viewWithTagNotCountingSelf:` (_but you can name it `-subviewWithTag:`_;) – staticVoidMan May 28 '14 at 22:44
  • Thanks for the link. Glad to know I'm not the only one who thinks this is a weird method. – soleil May 28 '14 at 23:09