I have a storyboard with 1 UIViewController, holding 1 UIView that contains a number of nested UIViews. I subclassed the View Controller to implement this method:
- (BOOL)shouldAutorotateToInterfaceOrientation: UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight || interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
I also added
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIInterfaceOrientation</key>
<string>UIInterfaceOrientationLandscapeLeft</string>
to the Info.plist.
In the viewDidLoad of the main UIView I'm doing this:
PASectionView* sectionView = [[PASectionView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, 180)];
[self addSubview:sectionView];
The problem is the control is only 756px wide instead of the expected 1024. See the screenshot below for details. I've been searching all over the web but I can't find a solution to this frustrating problem anywhere. I'm using Xcode 4.5 with iOS5.1 set as base SDK.
EDIT
It's working by replacing frame with bounds. However I don't understand what's happening so it isn't working with the frame size.
The frame rectangle, which describes the view’s location and size in
its superview’s coordinate system.
#property(nonatomic) CGRect frame
and
The bounds rectangle, which describes the view’s location and size in
its own coordinate system.
#property(nonatomic) CGRect bounds
Use bounds, not frame.
Set the autoresizingMask to whatever views you want to autoresize on rotate. Like this:
[myView setAutoresizingMask:UIViewAutoresizingMaskFlexibleWidth | UIViewAutoresizingMaskFlexibleRightMargin];
The problem is because before loading into Landscape mode your lines of code is calling the method loading
in which method are you calling this [PASectionView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, 180)];
[self addSubview:sectionView]; if it is view controller class then it should be [PASectionView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 180)];
[self addSubview:sectionView]; if it is subclass of UIView then where did you get the ViewDidLoad method.
Now to solve your problem
in .h class:
write this
PASectionView* sectionView;
in .m class implement this method
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
if (toInterfaceOrientation == UIInterfaceOrientationPortrait)
{
}
else // OrientationLandscape
{
sectionView.frame = CGRect(sectionView.frame.origin.x,sectionView.frame.origin.y,self.view.frame.size.width,180);
}
You have to set the Auto resizing mask for your subview,
Add this line of code before adding the subView to the superview, if your subView is added by code.
yourSubView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
else if your subView added in nib file, select the border magnets and resizing masks in the properties of your subView in the nib file.
Related
I have a NSSplitView as my "Superview". In this SplitView is a Custom View with a NSTableView. I'm try to load my Custom View from a Controller class and then adjust the size of the custom view and the Table. But the table and or the custom view don't get resized. What i'm doing wrong?
Here is my controller class method where i load and set the size of the custom view:
// Header File
#property (weak) IBOutlet NSView *navigationView;
#property (strong) AppsNavigationViewController *navigationViewController;
// Implementation
- (void) initNavigationView :(id)viewControllerClass :(NSString*) viewNibName {
_navigationViewController = [[viewControllerClass alloc]
initWithNibName:viewNibName bundle:nil];
// add the current custom view to the parent view
[_navigationView addSubview:[_navigationViewController view]];
[[_navigationViewController view] setAutoresizingMask:
NSViewHeightSizable|NSViewWidthSizable];
// set the bounds of the custom view to the size of the parent view
[[_navigationViewController view] setBounds:[_navigationView bounds]];
[_navigationViewController setDelegate:self]; // not relevant
[_splitView adjustSubviews]; // checked. contains the _navigationView
}
And here is how it looks:
EDIT
I subclassed some views and draw different backgrounds. And it's definitely the custom view which don't get the size!
It seems maybe your table's frame is not at the origin of its super view. First, try setting the frame instead of the bounds and you could call this after you do that.
[[_navigationViewController view] setFrameOrigin:NSMakePoint(0,0)];
Normally though I usually set the frame/bounds like this because your superview's bounds may not be at {0,0} of its superview...
NSRect newFrame;
newFrame.origin.x = 0;
newFrame.origin.y = 0;
newFrame.size.width = [[someView superview] frame].size.width;
newFrame.size.height = [[someView superview] frame].size.height;
[someView setFrame:newFrame];
I just started a brandnew project GrafLaboratory to do some experimenting on drawing in NSView.
I added a custom view to the main window and configured it to adopt it´s size when the window changes it´s size.
I modified my InitFrameWith to this:
- (id)initWithFrame:(NSRect)frame
{
self = [super initWithFrame:frame];
if (self) {
NSRect r = [self bounds];
}
return self;
}
When I start my new app the first time and ask for [self bounds] I get the correct value: {{0, 50}, {600, 450}}. I then change the size of the window by dragging with the mouse. When restarting my app initWithFrame returns the same value: {{0, 50}, {600, 450}}.
But I the new changed size. I already tried several things but without success.
Any clues what I´m doing wrong?
Thanks, Ronald
The initWithFrame is only relevant when you initialize the object within a frame.
If it's a custom UIView with custom drawing, then look at:
- (void)drawRect:(NSRect)frame
That will get called when setNeedsDisplay is called and/or the view is resized.
With some custom views, one thing I've done in initWithFrame is to set the autoresize masks:
// subviews autoresize
[self setAutoresizesSubviews:YES];
// set resize masks (springs)
[self setAutoresizingMask:(NSViewMaxXMargin | NSViewMinXMargin |
NSViewMaxYMargin | NSViewMinYMargin |
NSViewHeightSizable | NSViewWidthSizable)];
Then in both init and drawRect, I call my layoutViews metod if the rect has changed:
- (void)drawRect:(NSRect)frame {
...
// called on resize. on init, delegate isn't hooked up so we'll skip
if (!NSEqualRects(_prevRect, [self bounds]))
{
[self layoutViews];
}
// stash away rect for comparison so layout view code only happens when the rect changes
_prevRect = [self bounds];
My layoutViews has custom layout logic.
Hope that helps.
I'm porting an iPhone app that uses this tutorial into a Mac app. I've been able to get text to display in NSScrollView, but I can't get the text to scroll and I hope someone knows what I am missing.
In the iPhone app, CTView is subclassed from UIScrollView
CTView.h:
#interface CTView : UIScrollView <UIScrollViewDelegate> {
1) But there is no NSScrollViewDelegate in AppKit. Is the missing delegate interface to NSScrollView the problem?
So for the Mac app, CTView.h looks like the following:
#interface CTView : NSScrollView
In CTView.m I have
[self setHasHorizontalScroller:YES];
[self setAcceptsTouchEvents:YES];
Also inside CTView.m I create a NSMutableArray of frames as
self.frames = [NSMutableArray array];
and fill the array up with frames. I also set the frame for the document view for the complete larger image that I want to be able to scroll through as:
[[self contentView] setFrame:[self bounds]];
[self.documentView setFrame: NSMakeRect(0, 0, totalPages * self.bounds.size.width, textFrame.size.height)];
The first frame is visible in the CTView, but when I move the horizontal scroll bar, the second frame doesn't show up in CTView.
I'm using Xcode 4.3.3 and Mac OS X 10.7.4.
Does anyone know what I need to do differently from UIScrollView for NSScrollView to be able to scroll through the frames?
Finally figured it out. Whew!
1) NSScrollView needs a view for its documentView, where the documentView is what is scrolled over. So in the nib I created a NSScrollView that contained a view for the documentView and set the documentView to that view as shown by the code in CTView.m
NSArray *viewArray = [self subviews];
NSArray *docViewArray = [[viewArray objectAtIndex:0] subviews];
NSView *docView = [docViewArray objectAtIndex:0];
[self setDocumentView:docView];
2) Then I added the array of frames, that would normally be added to UIScrollView, to the documentView of NSScrollView. The array of frames consists of multiple elements of content.
while (textPos < [attString length]) {
CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(textPos, 0), innerPath, NULL);
CFRange frameRange = CTFrameGetVisibleStringRange(frame);
CTColumnView* content = [[[CTColumnView alloc] initWithFrame: NSMakeRect(0, 0, self.contentSize.width, self.contentSize.height)] autorelease];
[docView addSubview: content]; // <<-- Here is where the frames are added to the documentView
textPos += frameRange.length;
}
And that did the trick.
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
}
}
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.