I have a tableview project which has a view, everything that I do in this view is controlled by "viewdidappear" method.
I added a new UIview which has "lines.h" and "lines.m" files.
I use this view to draw some lines and works god.
This extra view is located in to a scroll view because is to long to display in to iPhones screen.
The problem is that viewdidappear doesn't reload the uiview data, it only works with viewdidload.
I have to close the application and reopen it to get my data reload.
First, try adding this line at the end of viewDidAppear method:
[self.view setNeedsDisplay];
Or:
[_linesView setNeedsDisplay];
Second, Provide some more information. Post the code in viewDidLoad and viewDidAppear.
Try calling [self setNeedsDisplay] in the lines UIView class to cause the view to redraw itself.
Related
I have a tableview project which has a view, everything that I do in this view is controlled by "viewdidappear" method.
I added a new UIview which has "lines.h" and "lines.m" files.
I use this view to draw some lines and works god.
This extra view is located in to a scroll view because is to long to display in to iPhones screen.
The problem is that viewdidappear doesn't reload the uiview data, it only works with viewdidload.
I have to close the application and reopen it to get my data reload.
First, try adding this line at the end of viewDidAppear method:
[self.view setNeedsDisplay];
Or:
[_linesView setNeedsDisplay];
Second, Provide some more information. Post the code in viewDidLoad and viewDidAppear.
Try calling [self setNeedsDisplay] in the lines UIView class to cause the view to redraw itself.
When I use this line of code in the viewDidLoad of the app's main viewController, it is just getting completely ignored:
[self presentModalViewController:nextController animated:YES];
The nextControler doesn't load, nothing at all happens.
I do know the code is being "executed" since I put an NSLog before and after it and also ran through the program with a breakpoint.
When I call this line elsewhere in the code, it works perfectly as expected, but in viewDidLoad it is being ignored.
So I tried this code to see if there would be any difference:
[self.view addSubview:nextController.view];
This is loading the nextController view over top of my main view but some of it is transparent so that the main view shows through, and when I try to click on a button in the nextController, it is actually NSLog'ing as a press on a button in the main view below it.
Does anybody have any idea what might be happening here?
Thanks in advance!
viewDidLoad is called before the view controller is inserted into the view controller hierarchy. That's why it just doesn't know how to present a modal view controller at this point. Try moving the code into viewDidAppear:.
on the main screen on my project I have a a TableView, with a navigationBar on top and toolBar on the bottom. The thing is, one of the buttons in the toolbar needs to slide up an UISegmentedControl from the toolbar. I have already implemented this control in a custom UIView, BUT, if i just add it to my rootviewcontroller.view and slide it into place, it will scroll with the rest of the table, which is undesired (I would like it to appear as an extension of the toolbar).
So, what do I do? In rootViewController I do
self.filterView = [[FilterView alloc] initWithTarget:self.tableView reloadDataSelector:#selector(reloadData)];
[[self.view superview] addSubview:self.filterView];
[[self.view superview] bringSubviewToFront:self.filterView];
I add the control view (self.filterView) to my view's superview, and that puts it above the tableview's scroll.
BUT, now the problem. As soon as the tableView goes out of view (I push another view on the navigationController, or specially if the app goes to background) this view gets re layed-out, and my controller view gets moved to (0,0).
The thing is, as far as pushing new views on the navigationController, I can kind of control it by repositioning it in viewWillAppear and viewWillDisappear in my rootViewController. But when the app goes to background and comes back those functions don't get called.
So, is there any way to
(a)prevent my controller view from being moved
(b)detecting when it has been moved unintentionally
(c)detecting coming and going from background from rootViewController
???
I know I can detect passes to background in appDelegate, but I wouldn't feel comfortable dealing with layout issues there.
Thanks!!
EDIT:
To add some info, if I do
NSLog(#"%#",[self.view superview]);
//I get <UIViewControllerWrapperView: 0x61589d0; frame = (0 64; 320 372); autoresize = W+H; layer = <CALayer: 0x615d9c0>>
EDIT2: I guess I could create my own wrapper UIView first, load all my current view hierarchy in it, and put the controller view there. Do you guys think that would be worth the trouble? isn't there a simpler way?
EDIT3: Ended up opting for changing my rootViewController from UITableViewController to UIViewController, and added the tableView programatically, as Phil suggested below. I can now control my main view as I like, and since I am putting my segmentedControl view there I can control how it is positioned, as opposed to before, when I was placing it in an UIViewControllerWrapperView, which I am not too sure who controls or what it does to it's subviews.
SO, just out of curiosity, does anyone know why the UIViewControllerWrapperView that was wrapping my UITableViewController's view was moving my UIView on coming back from background??
To clarify, the setup was like so:
UIViewControllerWrapperView
|
|UITableView
|Custom SegmentedControl UIView
As a side note, you have a pattern in your code that looks like that view is going to leak and addSubview will automatically put the view on the top of the view order.
However, the reason your view is scrolling is because it is being added as a subview of the UITableView, which is a subclass of UIScrollView. When the scroll view scrolls, it will move any subviews up or down by the contentOffset property. As the UIScrollView scrolls it will repeatedly layout its subviews. Since the table view isn't aware of your custom subview, it appears it is just moving it to the 0,0.
I assume you are using UITableViewController. If you plan to have more than just a table view for this view controller, then you should implement a standard view controller instead. This controller would have a normal view that contains the tableview and your other views. UITableViewController is merely for convenience for a very common case.
It's very easy to duplicate UITableViewController's functionality if you are worried about that. It is actually very clearly documented.
When the table view is about to appear
the first time it’s loaded, the
table-view controller reloads the
table view’s data. It also clears its
selection (with or without animation,
depending on the request) every time
the table view is displayed. The
UITableViewController class implements
this in the superclass method
viewWillAppear:. You can disable this
behavior by changing the value in the
clearsSelectionOnViewWillAppear
property.
In your implementation:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if ([self.tableView numberOfSections] == 0) {
[self.tableView reloadData];
} else {
[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:animated];
}
}
When the table view has appeared, the
controller flashes the table view’s
scroll indicators. The
UITableViewController class implements
this in the superclass method
viewDidAppear:.
In your implementation:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self.tableView flashScrollIndicators];
}
It implements the superclass method
setEditing:animated: so that if a user
taps an Edit|Done button in the
navigation bar, the controller toggles
the edit mode of the table.
In your implementation:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated];
[self.tableView setEditing:editing animated:animated];
}
I have taken one subView of type UIView on the top of UIViewController. I want to remove it and again load it after clicking on button. But I am unable to remove it.
I have used [subView removeFromSuperview] method. But it is not working.
Try out the method inside the AppDelegate. If you have loaded the rootViewController.view as a subview to your window, try to unload it again, you should see a white screen.
[self.window addSubview:rootViewController.view];
[rootViewController.view removeFromSuperview];
Also, insert this line before you removeFromSuperview in your code:
NSLog(#"%#",[rootViewController.view superview]);
Replace rootViewController.view with your view. If the log reads (null), it means you have incorrectly assigned your view as a subview.
I have 3 ViewControllers 1.Main 2.Gallery 3.Text. What my problem is that i have the GalleryViewController using an External UIView with the name GalleryItemView. So once the view controller calls this inside the UIView i have a button that changes the subview so what i do is use the [super addSubView:newView]; eveything works out great but when i return to the GalleryViewController my app crashes so im guessing im doing this wrong. also what i notice is that once i change Views from pressing the button inside the GalleryViewController takes me to the menu and when i do a swipe gesture it scrolls horizontal and i do have a scrollview in the GalleryViewController Class so maybe what im doing is adding a subview to the ScrollView anyone know how i can fix this?
For starters:
[super addSubView:newView];
is pretty much incorrect.
Adding a view to a viewcontroller, you want to do
[self.view addSubview:galleryItemView];
[self.view bringSubviewToFront:galleryItemView];
If you believe you have added it properly, you could do the following to verify it:
if ([galleryItemView.superview isKindOfClass:[UIScrollView class]]){
NSLog(#"galleryItemView's parent is a scrollview");
}
Please post the crash if you still have problems.