0

I am writing a subclass of UIScrollView right now, and as part of what I am doing I need a second scrollView to contain all of the subviews.

The reason for this is that the second scrollview will have an 'actual' content size, while the subclass scrollview will have a larger content size, and in the -scrollViewDidScroll: I change the second scrollView's content offset based on the actual content offset.

When the user adds a subview to the scrollView, it will actually add it to the second scrollView.

One problem that I originally encountered was that the UIScrollView class adds two views to the scrollView (the scroll indicators) and I want to leave those be.

A workaround that I found, which is the top answer here (with modifications), that works for what I want is to get the name of the sender class in the -addSubview method like the following:

NSString *sourceString = [[NSThread callStackSymbols] objectAtIndex:1];
// Example: 1   UIKit                               0x00540c89 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1163
NSCharacterSet *separatorSet = [NSCharacterSet characterSetWithCharactersInString:@" -[]+?.,"];
NSMutableArray *array = [NSMutableArray arrayWithArray:[sourceString  componentsSeparatedByCharactersInSet:separatorSet]];
[array removeObject:@""];
if (![[array objectAtIndex:3] isEqualToString:@"<redacted>"]) {
    //My code here
}
else {
    [super addSubview:view];
}

Although this code block works and I am getting the results that I want, it seems kind of hacky, and requires checking if the calling class is "", which I would assume means that it doesn't want me to see its name. I am worried that using this method would cause problems if anything is changed in the future or if some other class has the value ""

Basically my question is (also TL;DR): Is there a better way (or more reliable) to check if the view being added (in -addSubview) is being added by the superclass (or even by self)?

Community
  • 1
  • 1
Jsdodgers
  • 5,253
  • 2
  • 20
  • 36
  • Sorry, I don't know of any other way to check, though I share your anxiety. Could you implement a different method (eg. `addUserSubview:`) for adding subViews, for use in your code, while super sticks to `addSubview:`? – pbasdf Sep 14 '14 at 14:40
  • The main reason I am avoiding doing that is because I want my subclass to be able to be used exactly like a scrollview, so that a class that thinks it is just a UIScrollView will use it correctly. – Jsdodgers Sep 14 '14 at 22:43

1 Answers1

0

you can create a custom uiview as a wrapper without any implementation.
WrapperView wrapperview = [WrapperView new]; wrapperview.view = theRealViewToAdd;
then you can test your custom views with [object isKindOfClass:[WrapperView class]].

donmarkusi
  • 346
  • 2
  • 13
  • I'm not quite sure what your solution is trying to do. I want to be able to determine what class called -addSubview (or more specifically I want to know if it was `super` that called it). – Jsdodgers Sep 13 '14 at 22:28
  • sorry then i missunderstood your question. is there maybe an alterative solution for your root problem, so you don't need to know super? – donmarkusi Sep 14 '14 at 10:29
  • Well, I am mainly trying to determine which views being added are the scroll indicators, so I suppose if there is a reliable way to distinguish those views from others, that would work as well. – Jsdodgers Sep 14 '14 at 22:45
  • A couple of ideas; apologies if you're ahead of me with these: – pbasdf Sep 15 '14 at 08:54
  • 1) do you know when super adds the scroll bars? Is it just during init? Or can it be anytime? If the former, you could override the init and set a flag before calling super init, and clear it just after (ditto for showsHorizontalScrollIndicator etc). Test for the flag in your addSubview. Or 2) could you have two scrollView subviews in your subclass, and have simple implementations of all the scrollView methods which call [scrollView1 method:] rather than [super method:]? And addSubview would do [**scrollView2** addSubview]. – pbasdf Sep 15 '14 at 09:06