iPhone view controller view shifted down 20 pixels when rotating to landscape - objective-c

I am trying to implement a custom tabbarcontroller using a UIViewController and a UITabBar. Everything is working fine so far, except when I rotate the device to landscape, the UIViewController shifts the entire view down 20pixels, creating a black bar between the status bar and the view. Even when the view is rotated back to portrait orientation, the view is still shifted down 20pixels.
What do I need to do to remove the black bar? Do I have to perform custom rotations? If so, where should I insert these rotations?
Before rotation:
After rotation:

I've experienced this same issue.
This discussion was helpful: UIWebView on iPad size
Tony's answer helped me discover that when you create a subview it's helpful to setup code similar to this:
UIWebView *webView = [[UIWebView alloc] init];
webView.frame = self.view.bounds;
If you post some of your code I may be able to provide more specific advice.

Rather than shifting all views down, try DELTA properties in Interface builder.

Related

iOS10 UIImagePickerController embedded as ChildViewController, not showing its subviews correctly

I am using an UIImagePickerController embedded in a square view container. It worked fine on iOS 8 and 9. On iOS 10, the internal objects of the UIImagePickerController will not stretch to the full width of the camera picker controller. See 2 screenshots:
The selected view in the view inspector is: CAMPreviewView (inside UIImagePickerController).
Here is the code I use for embedding the UIImagePickerController as a subview:
- (void) presentCameraInWindow {
[self addChildViewController:self.videoRecorder];
[self.cameraHolder
addControls:#[self.videoRecorder.view]
align:VerticalAlignStretchToFullHeight
withHeight:self.view.bounds.size.width
verticalPadding: 0.0f
horizontalPadding:0.0f];
[[self.videoRecorder view] setNeedsLayout];
[self.view layoutIfNeeded];
[self.videoRecorder didMoveToParentViewController:self];
}
NOTE: addControls is a vertical Layout engine i built which I use everywhere. It creates constraints automatically, programmatically, so i don't have to.
I call this set up in viewDidLoad.
The same issue occurs, if i don't use Constraints, and I set the frame of the UIImagePickerController manually.
We can clearly see in the view inspector that the UIImagePickerController is laying out correctly (to the full width and height of the container view, but it's internal subviews are not).
Also: Using AVFoundation directly is not an option right now, because of the effort involved.
I was not able to embed the UIImagePickerController in a subview that had a smaller frame than that of the Parent View Controller. So I embedded the UIImagePickerController in the self.view of the View controller housing it. Then I sent it to back, putting overlays on top of it as needed. I also ended up moving up its frame by a certain amount, since my app works with square videos. So it doesn't mind if I move its frame partly outside of the visible screen coordinates, as long as I don't try squishing its frame smaller than the size it wants to be. If I do that, then the internal viewfinder subviews inside UIImagePickerController start to lay-out unexpectedly (cut off). Again, this issue occurs on iOS10 only.

Uiwebview in uiscrollview tips

I have a UIScrollview to allow for pagination, and a UIWebview on the detail views inside. I know you are not supposed to do that according to Apples Class Reference, but I don't see another option.
In order to make responses and experience a bit better, I disabled scrolling of the UIWebview, with:
[[[webView subviews] lastObject] setScrollEnabled:FALSE];
But now I am looking for a solution to make the webview the right size, depending on the content. Is there an easy way to do this, where the width of the webview stays the same, but the height grows (automatically) when that is required to show the full article? This will remove the scrolling problem, as it sit he scrollview who will take care of all the scrolling in this scenario.
Does that make sense?
From the documentation for UIWebView, it states:
Important: You should not embed UIWebView or UITableView objects in
UIScrollView objects. If you do so, unexpected behavior can result
because touch events for the two objects can be mixed up and wrongly
handled.
A more appropriate approach would be to add your UIWebView to a UIViewController with a UIScrollView (or UITableView) underneath. I'd be conscious of the amount of space you'll have left though for the scroll view though, especially if you're dealing with the iPhone.
Hope that's a nudge in the right direction.
Update:
After looking into this (I was sure there would be a way), it seems the best approach I managed to come up with is to add your UIWebView to the header view of a UITableView.
//create webview
_webView = [[UIWebView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 280.0)];
//load request and scale content to fit
[_webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.stackoverflow.com/"]]];
[_webView setScalesPageToFit:YES];
//add web view to table header view
[[self tableView] setTableHeaderView:_webview];
This adds a UIWebView to the header of the table view before the cells are displayed underneath. Note that a table header view (and footer views also) are different from section headers (and footers) so you can still use these two if you are using UITableViewStylePlain.
Be sure to attenuate the frame of the webview to allow for any cells underneath to be visible or else the user will not be able to scroll the tableview as any touches will be intercepted by the webview.
This still goes against the UIWebView documentation (stated above) but, in practice, this implementation actually works fine as long as the webview does not cover the entire scrollable region of the view.
Here's a screenshot of the test app I made:
Hope that helps :)
There is a better way to do this.
From iOS 5.0 onwards, apple expose the UIScrollView present inside the UIWebView. So to resize the webview based on the contents, here is what you do.
Make the parent of UIWebView the delegate to that UIWebView.
Implement the webViewDidFinishLoad: and in that function just do this.
CGSize sz = [webView.scrollView contentSize];
CGRect rect = webView.frame;
rect.size.height = sz.height;
webView.frame = rect;
Even if there are multiple load start and finish, it does not matter since eventually we will have the web view resized to fit the contents.
In case you don't want the user to see the dynamic resizing, you can just set the alpha of webview to 0 and when everything loads and you are done with resizing, you can transition it to alpha 1 with animation.

How Can I set UIWebview or UIWindow in Landscape Mode in Global function?

I cannot use viewcontroller because viewcontroller crushed to unity(Game engine's name)'s application somehow. I needed to make my objective-c view in landscape to match unity's display.
I have searched on internet but what I found is force setting in controller.
So I want set UIWebView or UIWindow in Landscape mode for iphone inside global function.
How Can I set the code for that?
Setting a UIView or UIWindow in landscape mode is simply a matter of drawing the view in landscape orientation.
What view controllers add is simply the possibility of handling the rotation in a specific way (allowing it or preventing it), but the end responsibility to draw in landscape/portrait is with your view.
As a concrete suggestion, you can try and use a CGAffineTransformation to rotate your view, if it makes things easier for you:
CGAffineTransform newTransform;
newTransform = CGAffineTransformMakeRotation(M_PI/2);
view.transform = newTransform;
but without further hints as to how your view is made up, I cannot help more.

UITabBar appears 20 pixels down?

I have created a UITabBarController and adding to a UIViewController subview.
My code is implemented programmatically.
The UITabBar is showed up 20pixels down the view.
UITabBarController *tabCtrl_obj = [[UITabBarController alloc]init];
[self.view addSubview:tabCtrl_obj.view];
How should i solve it?
It's the status bar that's doing it. Sometimes if you add a view directly to the window it can behave oddly - generally it means you have to define more elements of the view yourself. Try reducing the size of your view by 20 pixels (probably to 460) and then removing the simulated status bar in interface builder. How much are you doing programmatically?

Removing views from UIScrollView

I have two UIScrollViews that I move images between. The user can drag and forth between the scroll views. I am trying to animate the movement of the image from one scroll view to another. In -touchesMoved (handled in my UIViewController which has two custom UIScrollViews that intercept touch and sends to my UIViewController), I am trying to set the "center" of my UIImageView that is being moved. As it is moved, the image gets hidden behind the UIScrollView and not visible. How do I make it appear on top of the UIScrollView? I am able to handle the -touchesEnded properly by animating in the destination scroll view.
I am also confused about -convertPoint:fromView: usage in the iPhone Programming Guide (See Chapter 3, Event Handling). If the touch coordinates are in window coordinates, to change my view (UIImageView inside a UIScrollView which is inside a UIView and inside a window) center don't I have to use -convertPoint:toView:, i.e.,
imageView.center = [self.view.window convertPoint:currentTouchPosition toView:imageView];
What am I missing?
You can use the method - (void)bringSubviewToFront:(UIView *)view for making the image view the front most view.
Johan
It depends on how you structured your views. If both scrollviews and the imageview are at the same level, it should work. If the imageview is a subview of one of the scrollviews, you can try bringing the scrollview to the front. That way also the imageview will be drawn over the other scrollview.
Johan
I have a View Controller with two ScrollViews. Images are added as subviews. ScrollViews are already in the front. I tried bringing scrollview to the front and also imageview of the scrollview to the front. But somehow when i drag, the center of the image goes over my other scrollview2 which i also tried sending back. But does not seem to work. Here is what i do, in TouchesMove (inside a ViewController)
view= [[scrollView1 subviews] objectAtIndex:currentImageIndex];
[self.view bringSubviewToFront:scrollView1];
[scrollView1 bringSubviewToFront:view];
[self.view sendSubviewToBack:scrollView2];
scrollView1 and scrollView2 are two scrollviews that are part of the ViewController's view.
Does this make sense ?
thanks
mohan