I need to add more number of NSView along with more number of customised NSOpenGLView in a window and then wants to shuffle the array of views. If I set the base view setWantsLayer:YES initially, I can't draw the OpenGLView if I set setWantsLayer:NO, I can draw OpenGLView but the NSView are goes beyond the OpenGLView. Like,
In MyOpenGLView.m
myOpenGLView = [ [ MyOpenGLView alloc ] initWithFrame:frame_ colorBits:16 depthBits:16 fullscreen:FALSE ];
[self addSubview: myOpenGLView];
Then I try to add one more view on window
customView = [[CustomView alloc] initWithFrame:[self bounds]];
[self addSubview:customView];
Now my custom View goes beyond the myOpenGLView. How do I fix this?
Edit:
Screenshot of Problem
Related
NSWindow
NSImageWell - with constraint to all four side of the Window's containerView
NSImage - is put in Well via NSPageControl
Using the mouse, I resize the Window and the ImageWell expands or contracts with the Window as desire.
The image in the Well remains the same size regardless of Window size.
The image does resize correctly, based on the size change of Window, if I drag the image a bit with the mouse.
How and where do I send a message to get this size to change "automatically" ?
Do I need to monitor size changes in the Window using Notifications?
Sorry, I was not clear. I want the image in the image well to maintain its
aspect ratio and to resize itself each time the Window is resized. Currently, when the window is resized, the user sees no change in the size of the image. He can however, cause the image to resize correctly by click dragging on the image or Window content view. I want the user to see this
resizing take place immediately, without needing to use the mouse. For example of an image that has an aspect ratio of 4/3. if the window is 4" x 4" , then when the image is added, it appears as 4" by 3". If the window goes to 8" x 8", then the image should automatically go to 8" x 6".
Guilherme was good enough to send me his demo NSView app. If, like in his app, I set an image in IB, my app also successfully resizes not only the ImageView but also the Image itself.
The problem appears to be because I put the images into the ImageView via an NSPageController. The only way to get the image to resize is to do a two finger drag inside the window.contentView
After Resizing window:
New Image Appears
Then following a two-finger drag on image :
<https://www.dropbox.com/s/d2he6bdzxbeefok/Screen%20Shot%202015-09-12%20at%2013.26.50.png?dl=0>
Below is relevant code:
AppDelegate follows:
#import "AppDelegate.h"
#import "MyImageView.h"
#interface AppDelegate ()
#property (strong, nonatomic) IBOutlet NSWindow *window;
#property (strong, nonatomic) IBOutlet NSPageController *pageController;
#property (strong, nonatomic) IBOutlet MyImageView *imageView;
#property (weak) IBOutlet NSTextField *infoLabel;
#property NSArray *imageArray;
#end
#implementation AppDelegate
#pragma mark Window delegate
- (void)windowDidResize:(NSNotification *)notification{
//[_window layoutIfNeeded];
//[_imageView doSelfLayout];
}
- (void)awakeFromNib {
[_window setDelegate:self];
[_imageView setTranslatesAutoresizingMaskIntoConstraints:NO];
_imageArray = #[ [NSImage imageNamed:#"eggplant.png"],
[NSImage imageNamed:#"sandwich.png"],
[NSImage imageNamed:#"yoghurt.png"]];
[_pageController setDelegate:self];
[_pageController setArrangedObjects:_imageArray];
[_pageController setTransitionStyle:NSPageControllerTransitionStyleStackBook];
// Set info label's text
NSString *info = [NSString stringWithFormat:#"Image %ld/%ld", ([_pageController selectedIndex]+1), [_imageArray count]];
[_infoLabel setStringValue:info];
}
#pragma mark Page Controller delegate methods:
- (void)pageController:(NSPageController *)pageController didTransitionToObject:(id)object {
/* When image is changed, update info label's text */
NSString *info = [NSString stringWithFormat:#"Image %ld/%ld", ([_pageController selectedIndex]+1), [_imageArray count]];
[_infoLabel setStringValue:info];
//[_window layoutIfNeeded];
}
- (NSString *)pageController:(NSPageController *)pageController identifierForObject:(id)object {
NSString *identifier = [[NSNumber numberWithInteger:[_imageArray indexOfObject:object]] stringValue];
return identifier;
}
- (NSViewController *)pageController:(NSPageController *)pageController viewControllerForIdentifier:(NSString *)identifier {
/* Create new view controller and image view */
NSViewController *vController = [NSViewController new];
NSImageView *iView = [[NSImageView alloc] initWithFrame:[_imageView frame]];
[iView setImage:(NSImage *)[_imageArray objectAtIndex:[identifier integerValue]]];
[iView setImageFrameStyle:NSImageFrameNone];
/* Add image view to view controller and return view controller */
[vController setView:iView];
return vController;
}
#end
What option have you selected for the scaling property in IB?
Here's a sample project, the image resizes automatically with Proportionally Up or Down selected.
I have made a demo Cocoa project zipfile below that has what I was looking for, namely an OS X app that :
- uses NSPageController in History mode to display an array of images (Portrait and Landscape) in a resizeable window
- imageView maintains imagefile aspect ratio as it automatically resizes
- images list can be traversed using a PreviousButton and a NextButton, or using a touch pad, with a two-finger swipe.
https://www.dropbox.com/s/7qgmg5dr1bxosqq/PageController3%203.zip?dl=0
It is pretty basic stuff, but I post it with the hope it can same someone else some time. Mark
I have a scrollview which has to display a view larger than the available display area.
I want to easily design the user interface without moving the embedded view up and down every time I have to do some changes.
The problem is everything outside the visible area is invisible in IB.
Is there any switch or trick to make everything visible in IB?
UPDATE
I have posted another solution here which I think is simpler and better, and works in storyboards.
ORIGINAL
Create your scroll view in the nib with the appropriate superview, position, and size.
Next, create a completely separate, top-level UIView instance by dragging a UIView out of the palette and dropping it into the work area outside of any existing views. In the Attributes inspector, set the Size popup to “None” and make sure the Status Bar, Top Bar, and Bottom Bar are all set to None. Here's an example:
This new top-level view will be your content view. Give your view controller two outlets: scrollView and contentView:
#interface MyViewController
#property (nonatomic, weak) IBOutlet UIScrollView *scrollView;
#property (nonatomic, strong) IBOutlet UIView *contentView;
#end
In the nib, wire up the scrollView outlet to the scroll view and wire up the contentView outlet to the content view.
Build your content view hierarchy inside the content view. Set its size as large as you need - it can be larger than 320x480 (as long as you have set all of its bars to None).
In your view controller's viewDidLoad, add contentView as a subview of scrollView and set scrollView.contentSize to the size of contentView:
#implementation MyViewController
#synthesize scrollView = _scrollView;
#synthesize contentView = _contentView;
- (void)viewDidLoad {
[super viewDidLoad];
[self configureScrollView];
}
- (void)configureScrollView {
CGSize size = self.contentView.bounds.size;
self.contentView.frame = CGRectMake(0, 0, size.width, size.height);
[self.scrollView addSubview:self.contentView];
self.scrollView.contentSize = size;
// If you don't use self.contentView anywhere else, clear it here.
self.contentView = nil;
// If you use it elsewhere, clear it in `dealloc` and `viewDidUnload`.
}
I want to create NSTextField programmatically. I am new to Mac App Development.
Can anyone help me in this ?
Update :
I tried this code
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSView *myView = [[NSView alloc] init];
NSRect frameRect = NSMakeRect(20,20,100,140);
NSTextField *myTextField = [[NSTextField alloc] initWithFrame:frameRect];
[myView addSubview:myTextField];
}
This does nothing. Please correct me if i'm wrong anywhere.
Thank you.
Creating UI elements programmatically is very simple in Cocoa.
It involves two steps:
Create the view and set a frame to it.
Add it as a subview to any super view.
Following snippet will you help you understand better.
NSRect frameRect = NSMakeRect(20,20,40,40); // This will change based on the size you need
NSTextField *myTextField = [[NSTextField alloc] initWithFrame:frameRect];
[myView addSubview:myTextField];
It looks like you're creating an NSTextField OK, but you're not adding it to anywhere visible in the view hierarchy. Your app probably contains one or more NSWindow instances; if you want a view to appear in a particular window, you should add it as a subview of that window's content view.
Has anybody used a NSScrollView to control scrolling using the cocos2d-mac framework?
After much struggling I managed to make UIScrollView work with cocos2d-ios. Any pointers to using NSScrollView together with a NSOpenGLView would be appreciated.
I finally managed to get a NSScrollView working within my cocos2d-mac Xib.
The trick is that you have to programmatically overlay the OpenGLView over the NSScrollView main view (leaving room for the scroll bars) by first setting up a fake view as the scrollView's documentView, and then removing the openGLView from its parent view and adding it again (so the OpenGLView is drawn over the ScrollView). You can do it as follows:
appDelegate = [[NSApplication sharedApplication] delegate];
// Set up NSScrollView with dummy empty view as big as the layer
NSRect rect = NSMakeRect(0, 0, myLayer.width, myLayer.height);
NSView *view = [[NSView alloc] initWithFrame:rect];
appDelegate.scrollView.documentView = view;
[view release];
// Push OpenGLView back to front
[appDelegate.glView removeFromSuperview];
[appDelegate.splitLeftView addSubview:appDelegate.glView];
And then, you should use the scroll bars events to update the myLayer position accordingly.
My NSWindow's contentView is an NSView subclass. It has some other NSView subclasses as subviews. The subviews are layer-based, and those layers in turn contain sublayers. Some of the sublayers have further sub-sublayers.
I want the whole thing to resize proportionally when the window is resized. What is the right way to set it up so that will happen?
Thanks
EDIT: I am not using Interface Builder at all.
Here's what I've done to get the contents of an NSView to scale proportionally as I resize the parent window. First, in interface builder, I added my NSView to the window, then added a reference to it in my AppDelegate. Mine happens to be called scrollView. I removed all of the auto-sizing behaviour from the scrollView.
Then, in my AppDelegate I added this:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// keep the aspect ratio constant so that the content looks good
[window setContentAspectRatio:NSMakeSize(2, 1)];
window.delegate = self;
}
- (void)windowDidResize:(NSNotification *)notification {
// size the scrollView to fill the window, but keep its bounds constant
NSRect rect = [[window contentView] frame];
NSRect oldBounds = [scrollView bounds];
[scrollView setFrame:rect];
[scrollView setBounds:oldBounds];
}
This turns the AppDelegate into the window delegate too. Fine since I've not got much logic in it. By keeping the bounds constant while changing the frame, the contents of scrollView will be scaled down smoothly.