Moving a UIButton programmatically? - user-interface

Right now I want to move the position of the button dependant if it is an iPhone 5 screen or not, but I am having trouble figuring out how to move the button, right now I have an "if statement" that can figure out if it is an iPhone 5 or not, but I don't know how to move my button inside the statement. Take a look at my code.
.h
-(IBAction)randomButton;
//the button I want to move
.m
- (void)viewDidLoad
{
[super viewDidLoad];
if (IS_IPHONE_5) {
//I don't know how to move the button in here.
}
}

The right place to put this programmatic layout is either in a layoutSubviews method (if, for example, the view controller's root view is a custom subclass) or in the viewDidLayoutSubviews method of your view controller class. In either of those methods, you can set the button's position and size by modifying its frame, like:
_theButton.frame = /*whatever*/
If you want to change the button's position without modifying the button's size you can adjust the button's center instead of its frame, but usually if you're doing programatic layout you want to set both the position and size in the same place.

If you need more complex layouts, you can also use 2 XIB files, one for iPhone 5 and one for iPhone 3/4. I typically do that as I can always see what it will look like without guessing or trial and error.

Related

How is a subview of an NSView dynamically positioned?

I am attempting to change the coordinates of an NSButton that is contained within a parent NSView and something is clearly not working, because the button position does not change. Both elements are defined in a nib file and the parent view has animation applied to it using CoreAnimation.
I have tried the following.
button.frame.origin.x = 500
and...
var frame:CGRect = button.frame
frame.origin.x = 500
button.frame = frame
Even with the animations disabled, I can not seem to dynamically position the subview. Is there some feature that prevents children views from being positioned programmatically?
Please note that I am using Swift with XCode 6.3.1.
I'm guessing you're using AutoLayout constraints, given you're using the latest tools.
If so, setting a subview's frame directly won't work the way you're expecting (if it does anything at all, it'll cause strange drawing glitches / flashing when mixed with animation). You have to create outlets for your layout constraints and modify them.
If you're not using AutoLayout, I suggest having a look at your button outlet to make sure it's actually connected (ie, you're not talking to nil). Even if the outlet is connected, make sure it's not nil at runtime - you may be trying to talk to the button before the nib is loaded and the outlet / action connections are restored.

How do I do something after the next NSView -layout has occurred?

In response to a user event, I want to:
add a new NSView to the window, and then
show an NSPanel positioned just below that view
I have each half of this done. I can add a new subview, and the container view's -updateConstraints identifies it and adds the correct layout constraints, so that the next time layout is performed, it's positioned correctly in the window. Also, I have a NSWindowController subclass that puts the panel on the screen.
Unfortunately, there's an ordering problem. My panel's controller just looks at the new NSView's frame property for deciding where to put it, but during this iteration of the main event loop, the -layout method hasn't been called yet, so it's still positioned at (0,0).
(If I separate these two pieces of functionality, and require two separate user events for "add view" and "create panel", then the panel is correctly positioned below the view.)
Is there a way to attach an NSPanel to an NSView, as if with a layout constraint? Or is there a way to say "do this (window controller stuff), but only after the next -layout call"?
Just call -layoutSubtreeIfNeeded on your NSView’s superview as soon as you add it and its constraints, so it will lay out immediately, then add the panel.
Or use an NSPopOver, although those draw a certain way and you might not want that.

Xcode 4, How to make other buttons fall off the screen after one is pushed.

As an example, I have 5 IBActions declared. When I push one, I want the other 4 to fall down off the screen. Any idea how to do this? Would I define a translation for each other IBAction??
A UIButton is a UIView. You can animate movement of a UIView; that movement can be to a position offscreen. (See the section under "animation" in the UIView class reference: http://developer.apple.com/library/ios/#documentation/uikit/reference/uiview_class/uiview/uiview.html) You might then want to remove the now-invisible buttons from their superview (in which case you'd need to retain them somehow or they might cease to exist), but you don't have to.
You will need a way to refer to the UIButtons. You can use IBOutlets for this, or you can "tag" the buttons in Interface Builder and use -[UIView viewWithTag:] to find the buttons you want to animate.
For a whole lot more on animation, see my book: http://www.apeth.com/iOSBook/ch17.html

Initiate a UIPicker from a UIbutton

I would like to make a UIbutton, by press it, it trigger the appearance of a UIPicker from bottom with animation.
May I know how and what code can i initiate the UIpicker from button? And where should i place and set the UIpicker in Interface Builder? and lastly, after choose from the picker, how can it move away?
Many thanks!
You need to look up some documentation on how to make a UIPickerView. There are tons of tutorials out there, even video tutorials. Just search around. It's part of becoming a good programmer.
I personally would set up my picker in interface builder, and set up an IBOutlet to it. I would then, in the .h file of your viewController, set up a method called
-(IBAction)showPicker
Them link the method to your button.
In your .m file of your viewController you should have
-(IBAction)showPicker
{
[UIView beginAnimations];//tells the compiler to start a new animation
[UIView setAnimationDuration:1.0];//in seconds
thepicker.frame = CGRectMake(100, 100, 200, 200);//move the picker to a specific position
[UIView commitAnimations];//tells the compiler to start the animations
}
the beginAnimations and commitAnimations is the code that says any code between us will be animated. So you can animate their alpha (transparency), their positions, and others as well. thepicker refers to your IBOutlet name, whatever you called your picker. I would move the picker out of the screen in your interface builder, then when you press the button, move it into postion with
thepicker.frame = CGRectMake(x,y,width,height);
then, to move it away, just use the same code but change the frame to be out of the screen when you animate it.
BTW, I would create your pickerView first in the viewdidload method, instead of creating it on tapping the button. Otherwise, you will constantly be creating UIPickerViews everytime the button is hit.

How to resize UI Table View of a UI Table View Controller programmatically?

I subclassed UITableViewController and called it FeaturedGamesViewController. Ok, I also have a navigation controller to which I added this FeaturedGamesViewController as the root. All pretty standard stuff that you do in the App Delegate.
Also note that there is no NIB file created for FeaturedGamesViewController. Just subclassing UITableViewController and calling initWithStyle sets the style of the table and sets the dataSource and delegate and size automatically. Data Source and Delegate are obviously set to FeaturedGamesViewController.
- (id)init
{
// Call the superclass's designated initializer
[super initWithStyle:UITableViewStyleGrouped];
}
OK, You see that I have set the table size to "Grouped". In Landscape view on my iPad it has about 20 pixels of space to the top, left and right (Sorry can't post screen shot because I am new here and the system won't let me until I have accumulated a certain number of points)
I DO NOT want that! This is Landscape so I expect it to fill up the all the space between the navigation bar and the tab bar below. What is worse is that I have faked a grid with a Custom UITableViewCell but the space to the left and right make it so that if you click on that space, the entire row is selected thus betraying the sense that this is a grid.
Now I figure I should resize the table view in viewDidLoad or something but I don't know how. I cannot do initWithFrame because of potential memory leaks (and possibly resetting dataSource and delegate and autoresizeMask properties that were already set) so there must be a setter or something to reset the origin of the tableview to just beneath the Navigation bar and filling up the entire screen with size 1024X748. How do you do dynamically reset the size of the table view?
Then I got really frustrated and I decided to do it via a Nib file, that way I can set the the orientation to landscape and set simulated Navigation and Tab bars and fill the rest of the space with the table view. This worked! If you are curious how to create a table view with a Nib after you have subclassed UITableViewController WITHOUT a nib, here is how:
http://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/TableView_iPhone/CreateConfigureTableView/CreateConfigureTableView.html#//apple_ref/doc/uid/TP40007451-CH6-SW10
Go to the paragraph right before "Creating a Table View Programmatically".
OK, when I did that, my landscape view of the "grid" looks filled up the entire space between the navigation bar at the top and the tab bar at the bottom just like I wanted.
I was fiddling with this some more and I found out that in my "non nib" version (the problematic one), I had set the table style to "grouped". When I changed it to "plain", it worked!!! But here is the thing though: In the nib version, "grouped" or "plain" gives the correct layout with the table occupying the whole space. So what gives?
Sorry for the long question but I guess what I am asking is:
1) How do you programmatically reset the size of the table view without introducing potential memory leaks or affecting other properties already set for you (ex: dataSource, delegate, autoResizeMask - these are set for you just because you subclassed UITableViewController)?
2) How do you do that for any view in general?
3) Why does "plain" style fill the layout as desired whereas "grouped" style gives the weird layout. Note that it this is not a problem in the Nib version.
Thanks for your patience!
Answer for (2), and hence for (1):
A UIView's frame is in a local coordinate system of its superview. A common way to make a view fit its superview is
CGRect bounds = [[self superview] bounds];
[self setFrame:bounds];
You should do this inside layoutSubviews.

Resources