In objective C, I'm trying to resize an application window after a button is clicked. If the window was 200x200, a (+) button is pressed to make it 200x210 or the (-) button is pressed to make it 200x190.
I'm just not sure how to set the size of windows after they're made in the editor.
Don't have sample code because it's simple and I'm not sure where to start.
Here you go:
- (IBAction)plusButtonClicked:(NSControl *)sender
{
NSRect frame = sender.window.frame;
frame.size.height += 20;
[sender.window setFrame:frame display:YES animate:YES];
}
Depending whether you want the top or bottom of the window to expand, you may also need:
frame.origin.y -= 20;
Have a look at setFrame:display: in the NSWindow Class Reference.
Related
I do heavily use auto layout in my new project, but I've got one issue related to NSWindow during resizing ...
NSWindow is borderless window,
during initial setup, frame of this window is set based on status item position and initial content view size (intrinsicContentSize of contentView),
vertical anchor attribute is set to NSLayoutAttributeTop,
horizontal anchor attribute is set to NSLayoutAttributeCenterX
... so far, so good. NSWindow is placed correctly, size is correct and everything looks good.
Whenever contentView is resized automatically because of auto layout, etc. final window position is correct, size is correct, ..., so again, so far so good.
What's the problem? When animation is in progress (window is vertically resizing), top of my window is jumping +- 1 pixel down/up/down/up/down/up/down/up/... until animation is finished. It looks pretty ugly ...
It behaves like this pseudo code ...
NSRect frameRect = window.frame;
while ( frameRect.size.height != desiredHeight ) {
frame.origin.y -= 1; // Move window down by 1px
[self setFrame:frame display:YES animate:YES];
frame.size.height += 1; // Increase window height
[self setFrame:frame display:YES animated:YES];
}
... it looks like auto layout changes origin of window and then auto layout realizes that the height should be changed as well, ...
Anyone did see this behavior?
Mea culpa, how can I missed it, it's because I do use NSLayoutConstraint for height of one of my views and I'm animating it via animator and it produces non integer values - so the height sometimes does contain real numbers and this is the cause for jumping top of NSWindow. Problem solved.
I have a tabbed application that I would like to have a scroll view on. I already have a few text fields and labels on that tab. The problem is, the keyboard hides some of the text fields. How would I add a vertical scroll to prevent that?
You can accomplish what you are looking for without a scrollview.
In you delegate method for you textfield, You can change the frame of the viewController's view.
something like
- (void)textFieldDidBeginEditing:(UITextField *)textField;
{
CGRect newFrame = self.view.frame;
newFrame.origin.y = - 40; // move the view up to the point your textfield is visible
self.view.frame = newFrame;
}
Then in Set it back
- (void)textFieldDidEndEditing:(UITextField *)textField;
{
CGRect newFrame = self.view.frame;
newFrame.origin.y = 0;
self.view.frame = newFrame;
}
Usually I animate this with 0.33 seconds duration.
The solution requires quite a bit of code, but here's the general idea of what you need:
You will need to add the text fields (and everything else for consistency) to a scrollView.
You need to setup the scroll view to have vertical scrolling space only, but set the scrollEnabled to false so that the user can't scroll it manually.
Then you need to listen to UIKeyboardWillShowNotification and UIKeyboardWillHideNotification and manually scroll it up/down as required.
I have (+) and (-) buttons... The (+) button should make the window longer in the downward direction, and the (-) button should undo what the (+) button did, by making it shorter from the bottom.
The point is, the frame should only be getting stretched from the bottom and most of the UI items should be staying in place - there are buttons on the bottom of the window that should follow the change in window height...
The problem is I'm using this to shift the window and sustain the same position of its contents...
NSRect frame = sender.window.frame;
NSLog(#"\nHeight and width of window frame: (%f,%f).\nThe x and y origin of the window frame: (%f,%f). ", frame.size.height, frame.size.width, frame.origin.x, frame.origin.y);
frame.origin.y -= 22;
frame.size.height += 22;
[sender.window setFrame:frame display:YES animate:NO];
NSRect viewFrame = mainView.frame;
viewFrame.origin.y -= 22;
viewFrame.size.height += 22;
mainView.frame = viewFrame;
But say you click the (+) button once; all the items shift up slightly while the frame gets longer. If you click (+) consecutively after the first press it will function as expected: the frame will move down and its contents will stay in place.
If you then clicked the (-) button once; all the items shift down slightly while the frame gets shortened. Clicking the (-) consecutively after the first press, it will just move the frame as expected.
It seems pressing the button the first time will move all the windows contents, while consecutive presses will function as intended... I'd like to know if I'm missing something about autosizing in the Interface Editor of XCode. Thank you.
Assuming that mainView is the main view in your window, you should not be modifying its frame manually. So long as you have your springs and struts (or constraints) configured properly, it should resize automatically with the window.
[mainWindow disableScreenUpdatesUntilFlush];
[mainWindow disableFlushWindow];
NSRect frame = sender.window.frame;
NSRect viewFrame = mainView.frame;
viewFrame.size.height += 25;
frame.size.height += 25;
frame.origin.y -= 25;
[sender.window setFrame:frame display:YES animate:NO];
mainView.frame = viewFrame;
[mainWindow enableFlushWindow];
This works fine. I couldn't get the NSView and the window linked so I just move them both manually and use disableFlushWindow to make it happen seamlessly at the same time.
I made an application which have a preferences window with 2 tabs.
The first tab have a lots of prefs settings in it, but the second one is very small...
I'd like that the tabview & the window resize when we switch between these 2 tabs.
I act like that, but it doesn't seems to work, when I switch view the "Networks settings" tab is being reduced and disapear (like if the height was going from origin to 0 with animation).
Here is my code (.m):
- (void)tabView:(NSTabView *)tabView
didSelectTabViewItem:(NSTabViewItem *)tabViewItem
{
NSRect frame;
int height;
if ([[tabViewItem identifier] isEqualTo:#"Panel settings"]) {
height = 400;
} else if ([[tabViewItem identifier] isEqualTo:#"Network settings"]) {
height = 200;
}
frame = [[tabView window] frame];
frame.size.height = height;
frame.origin.y += height;
[[tabView window] setFrame:frame display:YES animate:YES];
}
Note that I linked the tab view to delegate.
My window is linked to the NSWindow * PrefWindow referencing outlet.
Thanks for your help!
I still think the problem is with the way your springs and struts are set in IB -- make sure you set them for not only for the tab view itself, but also for the individual objects in the view of the tab view item. I noticed that the default settings for my subviews had them all with the top strut set which made any subviews near the bottom of the view disappear when the window shrunk.
How can I make my NSWindow with NSTabView smoothly resize when user clicks a tab? I want it to like "System Preferances" application: window changes its size according to content.
Use NSWindow's setFrame:animated: method. If you want to resize the window down, make sure you decrease the y coordinate of the origin by the same amount you increase the size of the window. To also resize the views in the window, make sure you set up their autoresizing properties correctly.
NSWindow *window;
CGFloat widthChange, heightChange;
NSRect frame = [window frame];
frame.size.width += widthChange;
frame.size.height += heightChange;
frame.origin.y -= heightChange;
[window setFrame:frame animated:YES];