NSStackView only shows newest custom view - objective-c

I have a custom view controller class. I want to instantiate multiple custom view controllers and add their views to my NSStackView. I add a new view to the stack view by clicking a button. The button calls this method:
[stackView insertView:myCustomViewController.view atIndex:0 inGravity:NSStackViewGravityBottom];
However, when a new view is added, it's added stackView.spacing below where the previous view was, but that previous view is no longer visible, however it is still listed as a view in my bottom gravity as evidenced when I call
NSLog(#"%lu",(unsigned long)[stackView viewsInGravity:NSStackViewGravityBottom].count);
I don't have this problem if I try adding NSButtons, so it's something to do with my custom view but I can't figure out what.
Please help. Thanks!

You should check that your custom view has constraints (or an intrinsic content size) that completely define the height of the view. If they don't, these views are collapsing down to 0 heights (this same thing has happened to me before).
You can check if this is happening by:
[stackView insertView:myCustomViewController.view atIndex:0 inGravity:NSStackViewGravityBottom];
[stackView layoutSubtreeIfNeeded];
NSLog(#"%f - %d", NSHeight(myCustomViewController.view.frame), [myCustomViewController.view hasAmbiguousLayout]);
With StackView, you'll see that the later ones print "0 - 1". The heights are 0, and they're ambiguous.
Vertical NSStackView's will only position views vertically, but won't give specific heights. (Same for horizontal stack views and widths).

Related

Removing objects from superview by clicking on subviews

I have a UIViewController which places it's view on the screen and when it loads it creates an array of CGRects. It then adds those CGRects onto its view as subviews by filling them with a UIView.
I then create another CGRect and place it within one of these subviews and fill it with a UIImageView. It's set up to use CGRectContainsPoint and if the point is within one of the UIView CGRects it passes data to that object saying that it is there.
I can then click the UIView and it will use handleTap: to remove the origin point of the UIImageView rect from the super view.
Now the problem, I recently implemented a NSTimer and have it dropping new UIImageViews in at certain times. I also used the CGRectContainsPoint for loop to iterate through the array of UIView rectangles to check for UIImageView rectangles within them every one second.
When I run the program, I can click to remove the initial one, but when I click another it may or may not remove itself, I don't know why. However, sometimes when I click the first ones blank square it will remove one of the other ones and vice versa.
Im not so sure about your problem. But i guess that you want to creat a view and when u click it ,it will be disappeared itself? And u try to add many of this views but it doesnt work directly u think.
See if i can help. you can creat a news class extends to UIView and add an tapGesture to it, which will refer to a method -(void)removeItSelf:(id)sender;
-(void)removeItself:(id)sender
{
[self removeFromSuperView];
}
and create any instance of this view, it will be removed no metter how many u create.

UIScrollView longer than VC

I've been working with some UIScrollView objects that are longer than the view controllers they are contained by (this is in storyboard). Right now if I want to move objects that aren't initially shown I have to resize both the view controller and the scroll view. I also have to do this to add new objects to an initially non-displayed area. I know that I can do these things with the dimension inspector, but if I do that I can't tell what the layout looks like.
Is there another way to do this? I haven't been able to find a way to make the scroll view "scroll" inside of storyboard/IB. And it's kind of a pain to do layout this way.

Alternating between several NSViews

What I need may be pretty basic, but I'm definitely not sure as to how to proceed (I've done that before but none of my choices seem that Cocoa-friendly).
Ok, let's say we've got 2 NSViews - one next to the other:
The one on the left serves as a menu.
The one on the right will show a NSView (from a different XIB perhaps?) depending on the selection on the menu.
My questions :
How should I go about loading the different NSViews into the rightmost NSView?
How do I make sure that the subview (the one currently active) is properly resized when the window is resized?
rdelmar's solution should work, but another approach, which may be simpler, is to use an NSTabView to handle switching between the content views. You can hide NSTabView's tabs using the settings pane in interface builder, or by calling [self.tabView setTabViewType:NSNoTabsNoBorder]. I'd probably use a table view for the left side. When the user selects a row, you do something like:
-(void)tableViewSelectionDidChange:(NSNotification *)notification
{
[self.tabView selectTabViewItemAtIndex:[self.menuTableView selectedRow]];
}
The NSTabView can/will take care of properly resizing its content views as long as you've set up its and its content views' autoresizing masks (springs and struts) properly.
You should be able to create a custom view in IB that looks like your yellow view, and set its resizing behavior to expand in both directions with window resizing. Then, when you get your new view (by just referencing one you already have or loading a new xib), add it as a subview of the custom view, and set its frame to that of the custom view. I think that views resize their subviews by default, so it should resize correctly with the custom view.

Resize master and detail view controllers in a split view controller?

I'm working in Xcode 4.2 and am developing an app where I want the menu screen to use a Split View. Really, all I need the Split View Controller for is to split some of the menu options into a left pane and right pane. I want to be able to set custom sizes for the master and detail view controllers, but nothing seems to be working for me. I've tried updating the frame sizes for each view controller with code like:
[self.view setFrame:CGRectMake(0, 0, 768, 502)];
in the viewDidLoad functions, but that doesn't seem to affect anything.
Is there a way to set custom sizes for the master and detail view controllers of a split view controller without instantiating the view controllers in say the AppDelegate.m file? I want to be able to edit each of the view controllers in the storyboard as they are menu screens with a lot of buttons and such.
Edit:
In iOS 8+, the relative widths can be changed by specifying the minimum/maximumPrimaryColumnWidth properties or the preferredPrimaryColumnFraction.
The below answer is still true for iOS < 8:
You can't change the sizes for a split view controller.
See here: http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/Introduction/Introduction.html
"The UISplitViewController class is a container view controller that manages two panes of information. The first pane has a fixed width of 320 points and a height that matches the visible window height. The second pane fills the remaining space."
Use MGSplitViewController. It offers similar API to UIViewController, but offering additional features, such as split position, which is what you need.
- (CGFloat)splitView:(NSSplitView *)splitView constrainMinCoordinate:(CGFloat)proposedMinimumPosition ofSubviewAt:(NSInteger)dividerIndex;
{
return proposedMinimumPosition + 238;
}
- (CGFloat)splitView:(NSSplitView *)splitView constrainMaxCoordinate:(CGFloat)proposedMaximumPosition ofSubviewAt:(NSInteger)dividerIndex;
{
return proposedMaximumPosition - 200;
}
before the above delegate method add [splitView addDelegate:self];

Cocoa Merging Custom Views

Currently, I have an NSStatusItem that, when clicked, shows a custom view below it. The view contains some information and text fields. What I need is for a separate custom view to merge with the first and appear below it, as in further down the screen, not on top or behind the original view. This needs to be a separate view because there are actually several custom view that will be appended depending on what the user does in the first view. I would like to be able to independently add or remove each of these without affecting the others. I've dug through apple documentation but I haven't found anything about putting one custom view inside another programatically.
NSView has an addSubview:positioned:relativeTo: method you can use to add and order views to appear above or below each other. Use superview: to access this method on a container from any of its subviews.
Edit:
Try adding both views to an NSSplitView with a hidden divider. To hide the divider, subclass NSSplitView and override the dividerThickness: method to return 0;