add subview to custom uiview in interfacebuilder - iphone

I have made a custom UIView composed of several subviews and added it to a Nib file.
The view is loading correctly, but my problem arises when I try to add a UIView to my custom UIView from InterfaceBuilder.
I would like the added subviews to go to the topmost subview of my custom UIView, but not surprisingly, the subviews are added to the root custom UIView.
I could do some magic in the init of the custom UIView, moving the added view around.
is there any alternatives?
Any thought on best practice to solve this?

That seems to be right, since when you add the customView, int the nib file, you dont have access to its child subView, that means adding views to this custom view, will add them to the root view and not the childs,
As you said you will have to do some workaround to make this work, such as using tags to define the views and then move them by code

You need to add your Custom UIView to subview of your Root view and all other subviews of root UIView as a subview of your Custom View.So that you can get what exactly you want.
You IB hierarchy should be like below...
--->Root UIView
--->Custom UIView
--->UItextField
--->UIlabel
--->UiimageView
If you adding your Custom UIView in a code, then you need to connect IBoutlet for all subviews and then make them all as a subview of your custom view.

There doesn't seem to be any clever solution.
Instead i ended up overriding layoutSubviews like this:
-(void)layoutSubviews
{
[super layoutSubviews];
for (UIView *subview in self.subviews){
if (![self.internalViews containsObject:subview]) {
[subview removeFromSuperview];
CGRect f =subview.frame;
f.origin.y += self.frame.origin.y;
subview.frame = f;
[self.contentContainer addSubview:subview];
}
}
}
Doing construction of the view i added all by subviews to the array internalViews. The contentContainer is the view intended to serve as parent for all InterfaceBuilder added view.

Related

UIScrollView as a subview does not scroll

When I set my UIScrollView to be the main view within Interface Builder, the scrolling works as expected. However, when I add the UIScrollView as a subview of UIView the scroll does not work.
So it seems my trouble begins when the UIScrollView is added as a subview to UIView.
The "User Interaction Enabled" it true for both view.
I though perhaps I might have to do something with in touchesBegan something lake passing the touches to the UIScrollView, but have not had much luck with that.
Has anyone seen this before?
scrollView.delegate = scrollView; //or nil may work
It's always good to show a complete working code snippet:
// in viewDidLoad:
//UIScrollview *myScrollView;
UIView_descendent *contentView;
// scrollview won't scroll unless content size explicitly set
[myScrollView setContentSize:contentView.frame.size];
I have not found a way to set contentSize in IB.

I have a UIView inside of a UIScrollView. How do I reference the parent UIScrollView?

I've finally figured out how to stick a UIView inside of a UIScrollView, but now I have the problem of not being able to call the UIScrollView (who is the parent of the UIView) from within my UIView.
I've tried something like:
UIScrollView *scrollView = (UIScrollView *)self.superview;
But that's not working. My thought process was that the superview would be the container for the current view (UIView), but that returned a UIView so I just casted it to a UIScrollView, which I turned out to not be the right guess.
When you call
[someView addSubview:someOtherView];
someView is automatically set as superview of someOtherView. In your case, if this
UIScrollView *scrollView = (UIScrollView *)[self superview];
does not work (you probably have a typo in your question as the "=" is missing), then you have a problem setting things up (If that's the case, post your setup code).
You can add the scrollView to the UIView, thorough IB or code.
Through code you can add as
[self.view addSubView:scView];
Before that you need to add all the fields, labels and TextFields to the ScrollView. and set tags to the fields for the reference.
if u add textfield in scrollView ...
[scView addSubView: TextFieldsName];

Setting static content in a UIScrollView through XIB

I need a UIScrollview to show some static content in my app. I have taken a UIScrollView through XIB and started adding some UIImageViews and textViews in to it. But after coming to the end of the scrollView the view is not exapanding anymore. I need more space so that I can add some more views below. Is there any way in which I can do this (through XIB and not through code).
I struggled a lot to get this done in a more elegant way then the solution described by Csabi.
It's really simple:
In your xib file just add a generic view which is not a subview of your viewController.view (i.e although this view is in your xib file, it is not a part of your viewController's view hierarchy.)
Then select this view and using size inspector set the width and height that suits your need. Add whatever objects you want to this view. Hook up this view to your viewController with an IBOutlet. (Let's call it IBOutlet UIView *myBigView).
in your viewController.view drag a ScrollView and adjust the size of the scroll view as you like. Hook this up to your viewController. (IBOutlet UIScrollView *scrollView)
Now it's super simple:
-(void) viewDidLoad{
[super viewDidLoad];
self.scrollView.contentSize = self.myBigView.bounds.size;
[self.scrollView addSubview:self.myBigView];
}
Yes it is you can define the height of the UIScrollView simply for example height:1800
now you get bigger UIScrollView then your view you can put your objects to scrollview, and if it is filled simply pull it upward and drag and drop other items when you are finished simply pull the scroll view to its position and you have it.
It is simple :)
Hope it helps
Ask if you have any other question

layoutsubviews only called once despite any device rotation

just what the title says: I create an empty UIView subclass and I add a subview to it, I create an empty layoutSubviews method and I add a breakpoint there. Then I build the project and the simulation stops when loading the view at that point in the layoutSubviews method. Everything is fine so far. I continue the simulation and I rotate the device (assuming that the view controller is set to allow any orientation) but layoutSubviews is never called again, despite I can see how my object is rotating.
Any idea?
OK, i will simplify my question: How do I create a custom UIView with some subviews and make it responsive to the device orientation? I don't need to use drawRect or anything, just subclass UIView, add a couple of subViews and handle them when the device is rotating.
Did you try setting the autoresizingMask on the UIView? For example like below:
someView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
From the UIView documentation:
'When a view’s bounds change, that view automatically resizes its
subviews according to each subview’s autoresizing mask'
If you set the autoresizingMask to something other than None it should mean that the layoutSubviews method is always called when the views bounds change.
I'm not sure if it's exactly the same but i ran into a similar problem. I was using a UISplitViewContoller (template from Xcode) and adding a subview into the DetailViewController. The layoutSubviews methods was not getting called on rotation because it was a subview of the main UIView in the ViewController. So i added this to the DetailsViewController to get it to work (detailView is my subview):
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
[super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
if (detailView != nil) [detailView layoutSubviews];
}

Anchor a UIView

I have a UITableViewController inside of a UINavigationController.
I want to have a UIView appear over the top of the table view but not susceptible to the scrolling of the table view.
I.e. if the table view is scrolled, the UIView should remain in the same position relative to the screen, rather than relative to the table view. It should appear anchored in a certain position.
What is the best way to achieve this?
EDIT: To clarify, the view should float transparently over the top of the table view.
Many thanks!
I also wanted to have a floating UIView over my tableView.
So, within my RootViewController (which is a UITableViewController), this worked for me
- (void)viewDidLoad {
/* mylabel is a UILabel set in this class */
[self.mylabel setUserInteractionEnabled:NO];
/* navigationController comes from higher up in the navigation chain */
[self.navigationController.view addSubview:self.mylabel];
}
Similar to what Peter said, create a UIView that will contain both the TableView and the subclassed UIView. Such as:
UIView *view = [[UIView alloc] initWithFrame:frame]; // Define frame as you like
[view addSubview:myTableView]; // This is the reference to your tableView
[view addSubview:myAnchoredView]; // This is the reference to your UIView "floating" subclass
You will also need to turn off user interaction for your floating view. I don't know if this will specifically pass the touches to the underlying UIView's or not though:
[myAnchoredView setUserInteractionEnabled:NO];
If this is blocking touches to your tableView, you may need to pass the reference to your tableView to the anchored view at initialization, then pass the touch events along. You can do this by overriding the touch response methods in UIResponder. (If there is a better way, someone please speak up.)
Do you mean the anchored view should appear transparent over the UITableView, or just above, i.e. anchored view uses top 20% of the available space, table view uses the rest?
In any case, create a UIView containing the anchored view and the table view. If you want the anchored view transparent over the table view, it's a bit tricky, because to scroll the table view, touches have to pass through the anchored view.
Add the surrounding view's view controller to the navigation controller instead of just the tableview.
I investigated how UIScrollView keeps its scrollIndicator above the UIScrollView's content and yet unmoving by examining a UIScrollView in the debugger.
The scrollIndicators are UIImageViews. And you can see they are direct descendants of the UIScrollView itself. You can also see that any scrolled content is also a direct descendent. So how is it that the scroll indicators don't move?
I tried updating the position of my static content constantly in - (void)scrollViewDidScroll:(UIScrollView *)scrollView this, surprisingly, works. I'm not sure if it is how UIScrollView itself does it, but without some private magic, it must be something like this.