Changing Popover view frame on fly - objective-c

When a popover is displaying how can I make its size variable depending on condition check? Is this functionality supported or not when working with a popover?
Here is my sample for changing frame size:
CGFloat newHeight = 200;
NSRect newFrame = [parentView frame];
newFrame.size.height = newHeight;
NSView* childView = someView;
[parentView setFrame:newFrame];
[self.view addSubview:childView];

Don't know if anything was changed but in 10.9 all you have to do is setContentSize on the popover, e.g.:
[popoverView setFrame:NSMakeRect(0, 0, 581, 581)];
[thePopover setContentSize:popoverView.frame.size];

You need to change the popupwindow.contentViewController property of the NSPopover to a new NSViewController with a different-sized view.
That is, resizing the view's frame will only result in weird drawing problems. To get the popover window to change size, the contentViewController must be changed.
Ideally, you would set up a new view controller which is essentially a copy of your existing NSViewController, but containing a view that is taller/shorter. But in the worst-case scenario, you can do something like this:
gPopoverWindow.contentViewController = [[[NSViewController alloc] initWithNibName: #"tempNibName" bundle: nil] autorelease];
NSView *v = self.view;
NSRect b = [v frame];
b.size.height += 25;
[v setFrame: b];
gPopoverWindow.contentViewController = self;
In my testing, this resulted in the popover beginning a shrink animation (because of being set to the temp view controller), then growing to its new size.

Related

How to get full screen bounds with correct orientation?

guys.
I have such problem: I need to use full screen for my view. So I use
[_activityIndicator setFrame:[[UIScreen mainScreen] applicationFrame]];
It's work perfect, but only in portrait view. What to do if my app have to work in landscape too?
Your app has a root view controller, which rotates in response to device rotation. So set your frame in terms of the root view controller's view. Use its bounds, not its frame.
You can get a reference to the root view controller through the main window. You can get a reference to the main window through the shared application:
UIWindow* theWindow = [[UIApplication sharedApplication] keyWindow];
UIViewController* rvc = theWindow.rootViewController;
UIView* mainView = rvc.view;
UIActivityIndicatorView* act =
[[UIActivityIndicatorView alloc] initWithFrame: mainView.bounds];
[mainView addSubview: act];
And then you retain a reference to the activity indicator in a property and set it spinning.
To get current screen bounds i use:
CGRect screenBoundsDependOnOrientation()
{
CGRect screenBounds = [UIScreen mainScreen].bounds ;
CGFloat width = CGRectGetWidth(screenBounds) ;
CGFloat height = CGRectGetHeight(screenBounds) ;
UIInterfaceOrientation interfaceOrientation = [UIApplication sharedApplication].statusBarOrientation;
if(UIInterfaceOrientationIsPortrait(interfaceOrientation)){
screenBounds.size = CGSizeMake(width, height);
}else if(UIInterfaceOrientationIsLandscape(interfaceOrientation)){
screenBounds.size = CGSizeMake(height, width);
}
return screenBounds ;
}

UIScrollView metro theme

I am attempting to create a "metro" styled UIScrollView. It is similar to how iTunes app handles panels in the new ios version which wont be named.
I can't figure out how to have my views layout/scroll so that the next view in the sequence shows up. I've tried all sorts of things like keeping the contentSize the screen width but moving each view over -10ish so it will show up like above. I've tried making scrollView whose bounds were smaller than the screen so it would show the part of the next view. Nothing works.
Here is diagram of what I'm trying to do:
It seems extremely trivial on paper but I can't seem to get it work.
I'm not sure if I'm misinterpreting your requirements - but this might be a starting point to see how you could set it up:
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect viewBounds = self.view.bounds;
CGRect scrollViewFrame = CGRectMake(0, 0, floorf(CGRectGetWidth(viewBounds) / 2.2), CGRectGetHeight(viewBounds));
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:scrollViewFrame];
scrollView.center = self.view.center;
scrollView.contentSize = CGSizeMake(CGRectGetWidth(viewBounds) * 3, CGRectGetHeight(viewBounds) * 3);
scrollView.pagingEnabled = YES;
scrollView.clipsToBounds = NO;
UIPanGestureRecognizer *gestureRecognizer = scrollView.panGestureRecognizer;
[self.view addGestureRecognizer:gestureRecognizer];
for (int i = 0; i < 3; i++) {
CGRect frame = CGRectMake(10.f + (i * CGRectGetWidth(scrollView.bounds)), 10.f, CGRectGetWidth(scrollView.bounds) - 20.f, (CGRectGetHeight(scrollViewFrame) * 3) - 20.f);
UIView *view = [[UIView alloc] initWithFrame:frame];
view.backgroundColor = [UIColor redColor];
[scrollView addSubview:view];
}
[self.view addSubview:scrollView];
}
Literally just put this in an empty viewController's viewDidLoad:
The key things to note are
contentSize needs to be wide enough for all the panels
clipsToBounds should be NO so you can see the additional views
The bounds of the scrollview is essentially the main view port
pagingEnabled should be set
I've grabbed the panGestureRecognizer from the scrollview and attached it to the containing view instead so that panning is detected in the bounds of the containing view (which is larger) otherwise you are restricted to only detecting scrolls within the scrollviews bounds

How to increase the height of NSTableHeaderView?

I need to implement a headerview with specific size and gradient. I have to insert images in certain cells of the headerview.Tried to create the cells for the headerview using the following code,but i was not able to customize the headerview.
[[tableColumn headerCell] setImage:[NSImage imageNamed:#"sampleHeader"]];
If I use the overridden subclass of headerview, I was not able to view the images or text in the header cell.Please provide me any pointers to solve this issue.
I was able to insert images and text by subclassing the NSTableHeaderCell.How to increase height of the NSTableHeaderView?
If I subclass both NSTableHeaderView and NSTableHeaderCell , was not able to view anything in the
headercell.I used the following code for setting headerview and headercell
[tableView setHeaderView:CustomHeaderView];
[tableColumn setHeaderCell:[[[CustomHeaderTableCell alloc] initImageCell:
[NSImage imageNamed:#"sample"]]autorelease]];
I have the same issue as given in the below url
http://lists.apple.com/archives/cocoa-dev/2002/Jun/msg00331.html
You don't need to subclass NSTableHeaderView.
I was able to change the height of the header view using the following snippet in the controller class:
-(void)awakeFromNib {
NSRect frame = tableView.headerView.frame;
frame.size.height = 26;
tableView.headerView.frame = frame;
}
It should be noted that the scroll view takes care of the layout. It automatically changes the frame of the headerView as necessary, but leaves the height intact. Resizing the clip view etc as suggested in the other answer is not necessary.
You can also create a NSTableHeaderView object, initialize it with a frame(rect with height and width) and set that NSTableHeaderView object to your table view.
NSTableHeaderView *tableHeaderView = [[NSTableHeaderView alloc] initWithFrame:NSMakeRect(0, 0, 120, 60)];
[myTableView setHeaderView:tableHeaderView];
[tableHeaderView release];
Following link helped me in solving the issue.
http://lists.apple.com/archives/cocoa-dev/2003/Feb/msg00676.html
You need to set the Frame for NSClipView, NSTableHeaderView and the CornerView
This is how I implemented the same in Code.
for(NSView * subview in [topScrollView subviews])
{
for(NSView * subSubView in [subview subviews])
{
if([[subSubView className] isEqualToString:#"NSTableHeaderView"] && [[subview className] isEqualToString:#"NSClipView"])
{
[subSubView setFrameSize:NSMakeSize(subSubView.frame.size.width, subSubView.frame.size.height+5)];//HeaderView Frame
[subview setFrameSize:NSMakeSize(subview.frame.size.width, subview.frame.size.height+5)];//ClipView Frame
}
}
if ([[subview className] isEqualToString:#"_NSCornerView"])
{
[subview setFrameSize:NSMakeSize(subview.frame.size.width, subview.frame.size.height+5)]; //CornerView Frame
}
}

UITableViewCell custom selectedBackgroundView background is transparent

I have the following code that creates a UIView that I assign to my UITableViewCell's selectedBackgroundView property. Everything works as expected, with the exception of the subview's background, which is transparent.
I use the same code to create a custom view that I assign to backgroundView, and that works fine.
What is causing that subview to be transparent for selectedBackgroundView, and how can I avoid that?
- (UIView*) makeSelectedBackgroundView
{
// dimensions only for relative layout
CGRect containerFrame = CGRectMake(0, 0, 320, 40);
UIView* containerView = [[UIView alloc] initWithFrame:containerFrame];
containerView.autoresizesSubviews = YES;
// dimensions only for relative layout
CGRect subframe = CGRectMake(5, 5, 310, 30);
UIView* subview = [[UIView alloc] initWithFrame:subframe];
subview.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
subview.backgroundColor = [UIColor redColor];
subview.layer.cornerRadius = 5;
subview.layer.borderWidth = 2;
subview.layer.borderColor = [UIColor greenColor].CGColor;
[containerView addSubview:subview];
return containerView;
}
As we can see from name of ivar selectedBackgroundView, this background shown by cell when it was selected.
I've to reload few methods (– setSelected:animated: and – setHighlighted:animated:) of UITableViewCell subclass to reset background color of subviews back to their values. Look's like UIKit do some magic in this template methods (iterating over all UIView subclasses and set their background to clearColor)
This code might be helpful for you:
UIImageView *cellImageView = [[UIImageView alloc]
initWithFrame:CGRectMake(0,
0,
cell.frame.size.width,
cell.frame.size.height
)];
cellImageView.contentMode = UIViewContentModeScaleAspectFit;
// normal background view
[cellImageView setImage:[UIImage imageNamed:#"*<ImageName>*"]];
[cell addSubview:cellImageView];
[cell sendSubviewToBack:cellImageView];
[cellImageView release], cellImageView = nil;
Here cell is an object of custom UITableViewCell.
Also you can set backgroundColor property.
I would try to set the alpha for both containerView and subView to 1.0
[containerView setAlpha:1.0];
...
[subview setAlpha:1.0];
this should make your controls totally opaque.
You could also create some images for the background and use that images in state of creating 2 views. Let's say you create 2 image (normalBackground.png and selectedBackground.png) and then set this images as cell background. Here is a nice tutorial.
Try setOpaque:YES on your views.
In the end, I ended up subclassing UITableViewCell which contained a custom view object, and that worked.

NSScrollView doesn't display vertical scrollbar after adding content

I've created an NSScrollView which itself contains a NSClippedView as content view (this is all default, created by IB). Inside the contents view there is the (default) document view.
This NSScrollView has horizontal scroller disabled and vertical enabled and, most importantly auto hide scrollers enabled.
When I add new views (via code, runtime) to the document view the scroller does not unhide automatically, until the moment I vertically resize the window (and which in turn resizes the scrollview as well). 1px is enough. Just the new painting of the window seems enough.
What I am looking for is triggering this by code: so when I add views to the scrollviews' content view I would like the scrollbar to appear.
int numberOfChildViews = 10; //hard coded for example here
int childViewHeight = 80; //same as above
NSRect rect = NSMakeRect(0, 0, [[self.scrollView contentView] bounds].size.width, [numberOfChildViews*childViewHeight);
[[self.scrollView documentView] setFrame:rect];
[[self.scrollView documentView] setBounds:rect]; //just added to make sure
Then I added the custom views to the document view, like:
for (int i=0; i<numberOfChildViews; i++) {
NZBProgressViewController *item = [nzbProgressArray objectAtIndex:i];
int y=i*[[item view] bounds].size.height;
rect= NSMakeRect(0, y, [[scrollView contentView] frame].size.width, [[item view] bounds].size.height);
[[item view] setFrame:rect];
currentPosition++;
}
I am using a FlippedView so the origin will be displayed in left-top, like so:
#interface NSFlippedClipView : NSClipView {
}
#implementation NSFlippedClipView
- (BOOL)isFlipped {
return YES;
}
- (BOOL)isOpaque {
return YES;
}
#end
And added the following code to the awakeFromNib
NSFlippedClipView *documentView = [[NSFlippedClipView alloc] init];
[documentView setAutoresizingMask:NSViewWidthSizable];
[documentView setBackgroundColor:[self.scrollView backgroundColor]];
[self.scrollView setDocumentView:documentView];
[documentView release];
The scrollbars should become visible as soon as the document view is resized to be larger than the current viewport of the scroll view. Are you resizing the document view when you add your subviews to it?
Ahh, it's my own bad. For future reference: if you want to move the origin (0,0) to left-top use a NSView instead of NSClippedView extended class with IsFlipped method overriden to YES.
Thanks irsk for answering.