UIView created in code only draws in portrait mode - objective-c

I'm trying to add a view to my controller, which is put into landscape mode programmatically with the follwoing code:
- (void)viewDidLoad {
[super viewDidLoad];
//EpisodeView *nextEpisode = [self getNextEpisode];
UIImageView *nextEpisode = [[UIImageView alloc] initWithImage:[UIImage imageNamed: #"default-background.png"]];
CGRect selfBounds = self.view.bounds;
nextEpisode.frame = selfBounds;
[self.view addSubview:nextEpisode];
}
The problem is that the added view draws itself in portrait mode, not in landscape. Can anyone please point out what I could have missed?
When I'm adding the same view using Interface Builder, all works perfectly fine. So, I think, I have missed some property or something like that.

You probably haven't added autoresizingMasks which are by default UIViewAutoresizingNone. IB has different defaults. Set them as needed.

Related

Adding subviews in NSWindow while resizing the windows, the UI gets jumbled

I have a window and a subview is added, this subview is the container of another view(accessed and added using NSViewController).
I have disabled autolayout and doing resizing from springs. The subviews gets resize correctly on window resize.
If I add / remove subviews keeping the window size same it works fine. But if I add subview and maximize it and then remove and then add, it gets jumbled.
Some time it happens straight forward as :
Open the main window (it opens in small size). Maximize it, then add the subview, the subview is added to its original size as drawn in xib. Expected behavior is the subview should get expand and cover the main window.
I am not able to find the solution. Please help me to fix this. The sample code and sample project is attached here.
//In AppDelegate
- (IBAction)buttonClicked:(id)sender {
if (!self.myVC) {
self.myVC = [[MyViewController alloc] initWithNibName:#"MyViewController" bundle:nil];
}
[self.containerView addSubview:self.myVC.view];
}
- (IBAction)clearClicked:(id)sender {
for (NSView *view in self.containerView.subviews) {
[view removeFromSuperview];
}
}
I got the answer,
Before adding the view to container view, I get the container's rect and set the frame for child view.
- (IBAction)buttonClicked:(id)sender {
if (!self.myVC) {
self.myVC = [[MyViewController alloc] initWithNibName:#"MyViewController" bundle:nil];
}
NSRect rect = NSMakeRect(0, 0, self.containerView.frame.size.width, self.containerView.frame.size.height);
[self.myVC.view setFrame:rect];
[self.containerView addSubview:self.myVC.view];
}

How to resize Window to dimension in VIew Controller for a OSX app?

I'm fairly new to Mac OSX Apps, but I'm trying to build an app with no status bar, and the dimensions are smaller. So what I did in my AppDelegate.m is:
-(void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
self.mainViewController = [[MainViewController alloc] initWithNibName:#"MainViewController" bundle:nil];
[self.window.contentView addSubview:self.mainViewController.view];
[self.window setOpaque:NO];
[self.window setStyleMask:NSBorderlessWindowMask];
[self.window setBackgroundColor:[NSColor clearColor]];
self.mainViewController.view.frame = ((NSView*)self.window.contentView).bounds;
}
Now, what I really want to do, is to get my window to look like, what I've built in my interface builder (can't post pictures yet). I've tried shutting off all the autosizing elements but when I run the simulator I get a clipped version of my interface (the size changes every run). It seem like the frame size is getting miscalculated, but I've done everything from the interface builder. I can programmatically set the shapes of the view, but is there a way to shut off all resizing and simply portray the xib file as what I see in the interface builder?
There are two ways you could approach this problem.
You add an AutoresizingMask to your ViewController:
[self.mainViewController setAutoresizingMask:NSViewAutoresizingFlexibleWidth|NSViewAutoresizingFlexibleHeigt];
You disable window resizing in the Interface builder like by setting its minimum and maximum size. This can also be done in code.
Edit: Thanks to trojanfoe for pointing out that you can also uncheck Resize in the Attributes Inspector.
You can easily resize your window programatically. Here's how:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
NSRect frame;
frame.size.height = 200;
frame.size.width = 200;
[window setFrame:frame display:YES animate:YES];
}

Prevent shutter animation from appearing full screen when using cameraOverlayView [duplicate]

I have a transparent view with a rectangle drawn onto it using CoreGraphics.
When the camera launches the custom overlay view is above the shutter animation.
What you see is the standard camera shutter with the custom rectangle above it.
How do I get it to go in the right place, underneath the shutter animation? I've looked at other sample code but it's for OS 3.1 and doesn't seem to do anything differently.
Here's my code:
-(IBAction)cameraButton{
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerCameraDeviceRear]){
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
//Add the OverlayView with the custom Rectangle
CGRect overlayFrame = CGRectMake(0.0f, 0.0f, 320.0f, 480.0f);
OverlayView *overlayView = [[OverlayView alloc]initWithFrame:overlayFrame];
picker.cameraOverlayView = overlayView;
[overlayView release];
[self presentModalViewController:picker animated:YES];
[picker release];
}
}
On the iPad this problem doesn't exist, and the overlay view is behind the shutter animation by default. But on the iPhone, the overlay appears at front.
I've found a solution that worked for me.
You have to set your overlay view as a subview in this method:
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
if (!viewController)
return;
UIView* controllerViewHolder = viewController.view;
UIView* controllerCameraView = [[controllerViewHolder subviews] objectAtIndex:0];
UIView* controllerPreview = [[controllerCameraView subviews] objectAtIndex:0];
[controllerCameraView insertSubview:self.overlayView aboveSubview:controllerPreview];
}
Hope it helps
Original source:
http://www.alexcurylo.com/blog/2009/06/18/uiimagepickercontroller-in-3-0/
You may not do anything else other than what you're already doing; if iOS decides to put your overlay view over the shutter, you'll just have to live with it (unless you want to risk getting rejected from the app store).
As an imperfect workaround, you could start your overlay with alpha=0 and then set alpha to 1 a second or two later. But there is no set time period that the shutter appears for before 'opening' (I think it depends on how long it takes to initialize the camera hardware), so sometimes your interface might not appear until late and sometimes might appear too early.
As of 4.3.3, the shutter animation is broken because elements are displayed on top, and then snap underneath when the animation starts. I've filed this as a Radar: http://openradar.appspot.com/radar?id=1204401
I answered a similar question here. What worked for me (in iOS 6) was setting the cameraOverlayView in navigationController:willShowViewController:animated.
- (void) navigationController:(UINavigationController*) navigationController willShowViewController:(UIViewController*) viewController animated:(BOOL) animated {
self.imagePickerController.cameraOverlayView = ...; // your camera overlay view
}

UIButton inside UIView doesn't respond to touch events

I've put a UIButton inside a custom UIView and the button is not receiving any touch events (it doesn't get into the highlighted state, so my problem is not about being unable to wire up a touch inside up handler). I've tried both putting it into the XIB in Interface Builder, and also tried programatically adding the UIButton into the UIView seperately, both ended with no luck. All my views are inside a UIScrollView, so I first though UIScrollView may be blocking them, so I've also added a button programatically exactly the same way I add my custom view into UIScrollView, and the button worked, elimination the possibility of UIScrollView could be the cause. My View's hiearchy is like this:
The button is over the image view, and the front layer isn't occupying my button completely, so there's no reason for me not be physically interacting with the button. At my custom view's code side, I'm creating my view as such:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
UIView *sub = [[[NSBundle mainBundle] loadNibNamed:#"ProfileView" owner:self options:nil] objectAtIndex:0];
[self addSubview:sub];
[sub setUserInteractionEnabled:YES];
[self setUserInteractionEnabled:YES];
CALayer *layer = sub.layer;
layer.masksToBounds = YES;
layer.borderWidth = 5.0;
layer.borderColor = [UIColor whiteColor].CGColor;
layer.cornerRadius = 30.0;
/*layer.shadowOffset = CGSizeZero;
layer.shadowRadius = 20.0;
layer.shadowColor = [[UIColor blackColor] CGColor];
layer.shadowOpacity = 0.8;
*/
}
return self;
}
I've tried all combinations of setUserInteractionsEnabled, and had no luck. (Yes, also set them to checked in Interface Builder too). I've also read in another question with a similar problem that I should try overriding 'canBecomeFirstResponder' to return 'YES' and I've also done that too. But the problem persists, I can't click the button. I've not given any special properties, settings to the button, it's just a regular one. My other objects in the view (labels below, image view behind the button etc.) are working properly without problems. What could be possibly wrong here?
Thanks,
Can.
UPDATE: Here is a quick reproduction of the problem: https://dl.dropbox.com/u/79632924/Test.zip
Try to run and click the button.
Looking at the test project, I believe your problem in the way you create TestView, you do not specify the frame for it, so basically the parent view is 0 size, and the subviews you see from XIB extending out of the parent view and thus do not get anything in responder chain.
You should either specify the frame when creating TestView, or adjust the frame after loading XIB file.
I have had this problem as well. The cause for me was that the UIButton superview frame was of height 0, so I believe that even though a touch was happening, it was not being passed down to the button.
After making sure that the button's superview took a larger rectangle as a frame the button actions worked.
The root cause for this problem on my side was a faulty auto layout implementation (I forgot to set the height constraint for the button's superview).
I've found the solution. I was initializing my custom view as:
MyView *view = [[MyView alloc] init];
I've initialized it instead with a frame of my view's size, and it started responding to events:
CGRect rect = CGRectMake(0,0,width,height);
MyView *view = [[MyView alloc] initWithFrame:rect];
Storyboard Solution
Just for anyone wanting a solution to this when using storyboards and constraints.
Add a constraint between the superview (containing the button) and the UIButton with an equal heights constraint.
In my case, I had selected embed UIButton in a UIView with no inset on the storyboard. Adding the additional height constraint between the UIButton and the superview allowed the UIButton to respond to touches.
You can confirm the issue by starting the View Debugger and visually confirm that the superview of the UIButton is not selectable.
(Xcode 11, *- Should also work in earlier versions)

iPad - xib ignoring orientation on view loads

iPad question:
We have views that we're initializing from .xibs, with each .xib containing both landscape and portrait layouts.
The first view we load respects the orientation of the device, but any subsequent views seem to have confusion over which orientation they should be using. Or, rather, they seem to ignore orientation altogether and go with whichever orientation the .xib file was saved with. (i.e. We saved a .xib file in landscape, and even though the device was held in portrait position, it loaded the view from the .xib with a landscape layout.)
This is how we're calling in these views:
Settings *settingsTEMP = [[Settings alloc] init];
self.settings = settingsTEMP;
[self.view insertSubview:settings.view atIndex:0];
[settingsTEMP release];
The first of the calls (the one that respects the device's orientation) is in the viewDidLoad. The second, which uses a different view (the one that doesn't respect the device's orientation) is in a method that's called after a button is pressed, but uses the same syntax.
If we put both into viewDidLoad, they both respect the orientation.
We've tried searching for anyone having similar issues but have been thus far unsuccessful. Thanks in advance for any help you can provide.
I use the following
UIInterfaceOrientation toInterfaceOrientation = self.interfaceOrientation;
if ((toInterfaceOrientation == UIDeviceOrientationLandscapeLeft) ||
(toInterfaceOrientation == UIDeviceOrientationLandscapeRight))
{
NSLog(#"vSettings UIDeviceOrientationLandscape");
CGRect contentRect = CGRectMake(0,0,1024,768);
vSettings.bounds = contentRect;
CGRect myFrame = vSettings.frame;
myFrame.origin.x = 0.0;
myFrame.origin.y = 0.0;
vSettings.frame = myFrame;
UIImage *image;
image = [UIImage imageNamed: #"Default-Landscape.png"];
[backGroundSettings setImage:image];
}
I hate having to do this as it seems a right fudge but it works for me. Called just after I create the view.