I'm trying to build an homepage launcher for my app...
Something like the one from Three20.
I don't want to reinvent the wheel, but solutions like Three20 are not what I'm searching for: they are not updated to the latest iOS systems or devices (retina, ARC, iOS5/6) and they do much more than what I need (I basically need a set of buttons with a label that rotate on device rotation).
Right now I'm trying to build a 2x3 buttons grid that rotates on device rotation, but the code looks pretty crappy and I steel need to add iPhone5 support...
- (void) updateLayoutForNewOrientation: (UIInterfaceOrientation) orientation {
if (UIInterfaceOrientationIsPortrait(orientation)) {
button1.frame = CGRectMake(20, 59, 130, 80);
button2.frame = CGRectMake(170, 59, 130, 80);
button3.frame = CGRectMake(20, 176, 130, 80);
button4.frame = CGRectMake(170, 176, 130, 80);
button5.frame = CGRectMake(20, 293, 130, 80);
button6.frame = CGRectMake(170, 293, 130, 80);
label1.frame = CGRectMake(20, 147, 130, 21);
label2.frame = CGRectMake(170, 147, 130, 21);
label3.frame = CGRectMake(20, 264, 130, 21);
label4.frame = CGRectMake(170, 264, 130, 21);
label5.frame = CGRectMake(20, 381, 130, 21);
label6.frame = CGRectMake(170, 381, 130, 21);
} else {
button1.frame = CGRectMake(20, 59, 130, 60);
button2.frame = CGRectMake(177, 59, 130, 60);
button3.frame = CGRectMake(328, 59, 130, 60);
button4.frame = CGRectMake(20, 155, 130, 60);
button5.frame = CGRectMake(177, 155, 130, 60);
button6.frame = CGRectMake(328, 155, 130, 60);
label1.frame = CGRectMake(20, 127, 130, 21);
label2.frame = CGRectMake(177, 127, 130, 21);
label3.frame = CGRectMake(328, 127, 130, 21);
label4.frame = CGRectMake(20, 223, 130, 21);
label5.frame = CGRectMake(177, 223, 130, 21);
label6.frame = CGRectMake(328, 223, 130, 21);
}
}
Is the "place stuff, rotate it" approach the only way to build this kind of component? Is there any alternative?
You maybe want to code this yourself, but there's a fantastic open-source launcher here:
https://github.com/fieldforceapp/openspringboard
put the button and the label inside a view.
Then, on rotate you have to rearrange just the views.
Furthermore, you can use a for to rearrange them, so you can get that effect with a little code.
-(void)setScreenIconsToInterfaceRotation:(UIInterfaceOrientation)toInterfaceOrientation {
NSArray * viewsArray = [NSArray arrayWithObjects:view1,view2,view3,view4,view5,view6, nil];
int currentIndex = 0;
for (UIView * currentView in ViewsArray) {
int x;
int y;
int xseparation = 20;
int yseparation;
int height;
int width = 130;
if (toInterfaceOrientation==UIDeviceOrientationPortrait || toInterfaceOrientation==UIDeviceOrientationPortraitUpsideDown)
{
x = currentIndex %2;
y = currentIndex /2;
height = 101;
if (currentIndex < 2) {
yseparation = 59;
} else {
yseparation = 16;
}
} else {
x = currentIndex %3;
y = currentIndex /3;
height = 81;
if (currentIndex < 3) {
yseparation = 59;
} else {
yseparation = 15;
}
}
[currentView setFrame:CGRectMake(x*width+((x+1)*xseparation), y*height+((y+1)*yseparation), width, height)];
currentIndex++;
}
}
This is the code for your example
then for ios6
-(void)viewWillLayoutSubviews {
[self setScreenIconsToInterfaceRotation:[[UIApplication sharedApplication] statusBarOrientation]];
}
and ios5
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[self setScreenIconsToInterfaceRotation:toInterfaceOrientation];
}
Related
,I would like to give the user the option to select the button size as per the user's choice ... Can I do this please?
mytweak.xm
UIButton *respringButton = [[UIButton buttonWithType:UIButtonTypeRoundedRect] retain];
respringButton.frame = CGRectMake(self.view.frame.size.width - 250, self.view.frame.size.height / 2 - 80, 60, 60);
[respringButton setImage:[UIImage imageWithContentsOfFile: respring] forState:UIControlStateNormal];
[respringButton setTitle:#"respring" forState:UIControlStateNormal];
[respringButton addTarget:self action:#selector(reboot) forControlEvents:UIControlEventTouchUpInside];
if(style != 1) {
respringButton.tintColor = tintColor;
} else {
if(defaultTheme1 == 0) {
respringButton.frame = CGRectMake(self.view.frame.size.width - 250, self.view.frame.size.height , 60, 60);
} else if (defaultTheme1 == 1) {
respringButton.frame = CGRectMake(self.view.frame.size.width - 250, self.view.frame.size.height , 80, 80);
} else if (defaultTheme1 == 2) {
respringButton.frame = CGRectMake(self.view.frame.size.width - 250, self.view.frame.size.height , 100, 100);
}
}
[respringButton centerVertically];
[myView addSubview:respringButton];
mytweak.h
- (void)centerVertically {
// Spacing between the text and the image
CGFloat spacing = 5.0;
// Lower the text and push it left so it appears centered below the image
CGSize imageSize = self.imageView.frame.size;
self.titleEdgeInsets = UIEdgeInsetsMake(0.0, - imageSize.width, - (imageSize.height + spacing),- 120.0);
// Raise the image and push it right so it appears centered above the text
CGSize titleSize = self.titleLabel.frame.size;
self.imageEdgeInsets = UIEdgeInsetsMake(- (titleSize.height + spacing), 0.0, 0.0, - titleSize.width);
}
#end
I have an Ipad Application which is made with "xib" files this is in landscape mode i want this to support for both"Landscape and Portrait" I want in programmatically
I written this code it is working but some error
when I run the application it is not detecting wether it is in landscape or portrait if I change to another orientation this method is working and calling and working also is there any thing I have to give
-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
if (size.width == 768) {
[self portrait]; // collection of Components with Portrait Size
self.forced = [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassRegular];
} else if (size.width == 1024){
[self landscape]; // collection of Components with Portrait Size
self.forced = [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact];
}
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
}
-(void)portrait
{
_mLogo.frame = CGRectMake(20, 40, 200, 80);
_mCodeTF.frame = CGRectMake(240, 65, 200, 30);
_mEnterBtn.frame = CGRectMake(470, 65, 50, 30);
adonLogo.frame = CGRectMake(550, 40, 200, 80);
_mView.frame = CGRectMake(20, 155, 730, 830);
_mThumbnilScroll.frame = CGRectMake(0, 0, 730, 830);
}
-(void)landscape
{
_mCodeTF.frame = CGRectMake(355, 70, 270, 30);
_mLogo.frame = CGRectMake(45, 31, 255, 110);
_mEnterBtn.frame = CGRectMake(670, 70, 70, 30);
adonLogo.frame = CGRectMake(755, 31, 255, 110);
_mView.frame = CGRectMake(12, 160, 995, 575);
_mThumbnilScroll.frame = CGRectMake(0, 0, 995, 575);
}
enter code hereUse
– willRotateToInterfaceOrientation:duration:
or
– didRotateFromInterfaceOrientation:
instead of viewWillTransitionToSize... .
One will be handed the new orientation and the other will receive the old orientation.
Working with the window's size.height or size.with is not a good idea for this puprpose or at least not by simply using an == operator.
I have a view which should have a different layout in portrait and Landscape mode. I implement a method to redraw my UI elements with Autosizing (no AutoLayout):
-(void)buildViewElements:(UIInterfaceOrientationMask)interfaceOrientation duration:(NSTimeInterval)duration {
if (interfaceOrientation == UIInterfaceOrientationMaskPortrait) {
NSLog(#"Portrait");
[UIView animateWithDuration:duration animations:^{
CGRect newImageFrame = CGRectMake(20, 15, 100, 100);
_personImage.frame = newImageFrame;
CGRect newNameLabelFrame = CGRectMake(128, 20, 172, 21);
_nameLabel.frame = newNameLabelFrame;
CGRect newNameDescFrame = CGRectMake(128, 41, 172, 21);
_nameDescriptionLabel.frame = newNameDescFrame;
CGRect newBorrowedFrame = CGRectMake(128, 64, 75, 21);
_borrowedLabel.frame = newBorrowedFrame;
CGRect newBorrowedValueFrame = CGRectMake(211, 64, 42, 21);
_borrowedValueLabel.frame = newBorrowedValueFrame;
CGRect newLendFrame = CGRectMake(128, 93, 75, 21);
_lendLabel.frame = newLendFrame;
CGRect newLendValueFrame = CGRectMake(211, 93, 42, 21);
_lendValueLabel.frame = newLendValueFrame;
CGRect newcontainerFrame = CGRectMake(0, 130, 320, [CNX_Tools getLargestAttributeOfSize:[[UIScreen mainScreen] bounds].size] - 194);
_tableContainerView.frame = newcontainerFrame;
CGRect newDetailFrame = CGRectMake(20, 0, 280, 29);
_detailSelector.frame = newDetailFrame;
CGRect newTableFrame = CGRectMake(0, 36, 320, newcontainerFrame.size.height - 39);
_tableView.frame = newTableFrame;
}];
}
else if (interfaceOrientation == UIInterfaceOrientationMaskLandscape) {
NSLog(#"Landscape");
[UIView animateWithDuration:duration animations:^{
CGFloat factor = 1.0f;
CGFloat diff = 0.0f;
if ([CNX_Tools getLargestAttributeOfSize:[[UIScreen mainScreen] bounds].size] <= 480) {
// iPhone4 size
factor = 0.8f;
diff = 10.0f;
}
CGRect newImageFrame = CGRectMake(75*factor-diff, 20, 100, 100);
_personImage.frame = newImageFrame;
NSLog(#"Bild Frame %f", newImageFrame.origin.x);
CGRect newNameLabelFrame = CGRectMake(20, 140, 210*factor, 21);
_nameLabel.frame = newNameLabelFrame;
CGRect newNameDescFrame = CGRectMake(20, 161, 210*factor, 21);
_nameDescriptionLabel.frame = newNameDescFrame;
CGRect newBorrowedFrame = CGRectMake(20, 184, 75, 21);
_borrowedLabel.frame = newBorrowedFrame;
CGRect newBorrowedValueFrame = CGRectMake(103, 184, 42, 21);
_borrowedValueLabel.frame = newBorrowedValueFrame;
CGRect newLendFrame = CGRectMake(20, 213, 75, 21);
_lendLabel.frame = newLendFrame;
CGRect newLendValueFrame = CGRectMake(103, 213, 42, 21);
_lendValueLabel.frame = newLendValueFrame;
CGRect newContainerFrame = CGRectMake(250*factor, 0, [CNX_Tools getLargestAttributeOfSize:[[UIScreen mainScreen] bounds].size] - 250*factor, 268);
_tableContainerView.frame = newContainerFrame;
CGRect newDetailFrame = CGRectMake(20, 10, newContainerFrame.size.width - 40 , 29);
_detailSelector.frame = newDetailFrame;
CGRect newTableFrame = CGRectMake(0, 49, newContainerFrame.size.width, 219);
_tableView.frame = newTableFrame;
}];
}
}
This method is called from method:
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
switch (toInterfaceOrientation) {
case UIInterfaceOrientationPortrait:
[self buildViewElements:UIInterfaceOrientationMaskPortrait duration:duration];
break;
case UIInterfaceOrientationPortraitUpsideDown:
[self buildViewElements:UIInterfaceOrientationMaskPortrait duration:duration];
break;
case UIInterfaceOrientationLandscapeLeft:
[self buildViewElements:UIInterfaceOrientationMaskLandscape duration:duration];
break;
case UIInterfaceOrientationLandscapeRight:
[self buildViewElements:UIInterfaceOrientationMaskLandscape duration:duration];
break;
default:
break;
}
}
The method getLargestAttributeOfSize: returns the largest size attribute (height or width).
If I start the view in portrait I can tapp an the table cells and method tableView: didSelectRowAtIndexPath: is called. After a rotation to landscape mode all cells are not selectable and I cannot scroll in the table. But, if I leaf this screen and call ist again (in landscape mode), the same table cells are selectable, the method is called and I can stroll trough the table. If I rotate the device to portrait, I have the same faulty behavior. After a rotation of my device I can not interact with my table and its cells.
Can someone help me please or have an idea what's my issue here?
Thanks!
My guess is that a superview of your UITableView is not adjusted correctly. The input can than never reach your UITableView, but when it is started fresh all is well. Probably the view of your UIViewController.
Try setting clipsToBounds:YES to the superviews to see if your tableView is actually out of the views bounds.
I'm animating a UIView, UIText, UILabel and UIImage element in my app to transition into position on button click which works perfectly. However the code I am using doesn't work on a UISlider and I can't figure out way. Can anyone help me out. My code is:
[UIView animateWithDuration:0.8f delay:0.0f options:UIViewAnimationOptionTransitionNone animations: ^{
if (!viewExpanded) { //x y width height
viewExpanded = YES; //going down
_blueMove.frame = CGRectMake(0, 0, 500, 150); //slide down panel
_titleLabel.frame = CGRectMake(30, 30, 247, 44); // player title
_timeElapsed.frame = CGRectMake(40, 95, 34, 21); //time counter
_duration.frame = CGRectMake(230, 95, 35, 21); //duration
_playerBg.frame = CGRectMake(0, 84, 320, 45); //player bg colour box
}else{ //going up
viewExpanded = NO;
_blueMove.frame = CGRectMake(0, 0, 500, 0);//slide down panel
_titleLabel.frame = CGRectMake(30, -40, 274, 44);// player title
_timeElapsed.frame = CGRectMake(40, -20, 34, 21); //time counter
_duration.frame = CGRectMake(230, -20, 35, 21); //duration
//_currentTimeSlider = CGRectMake(40, 0, 175, 34); //time slider
_playerBg.frame = CGRectMake(0, -45, 320, 45); //player bg colour box
}
You can see I've commented out an example of what I'm using in the else statement to animate my UISlider but this throws up an error.
Thanks for any help.
The code you have posted has the slider commented out
//_currentTimeSlider = CGRectMake(40, 0, 175, 34); //time slider
And it's also missing .frame
I'm pretty certain I'm going about this in the completely wrong way now - but before I abandon ship & start again I thought I'd ask... I basically need to be able to detect the device that is using the app (iPhone 4 or iPhone 5) & the orientation the device is in & then adjust the output of my viewcontroller based on these - here is what I have:
To detect device (ok it doesn't detect device it's just if it's a bigger screen but thats OK for me!):
#define IS_IPHONE_5 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 ) < DBL_EPSILON )
Using the macro to detect device, along with code to detect orientation & then adjust view:
- (void)doLayoutForOrientation:(UIInterfaceOrientation)orientation {
if (UIInterfaceOrientationIsPortrait(orientation)) {
_Logo.frame = CGRectMake(97, 50, 127, 150);
_timeLabel.frame = CGRectMake(17, 248, 286, 21);
_years.frame = CGRectMake(70, 277, 35, 50);
_yearsLabel.frame = CGRectMake(64, 335, 42, 21);
_months.frame = CGRectMake(145, 277, 35, 50);
_monthsLabel.frame = CGRectMake(131, 335, 58, 21);
_days.frame = CGRectMake(220, 277, 35, 50);
_daysLabel.frame = CGRectMake(216, 335, 39, 21);
_hours.frame = CGRectMake(70, 393, 35, 50);
_hoursLabel.frame = CGRectMake(62, 451, 46, 21);
_minutes.frame = CGRectMake(145, 393, 35, 50);
_minutesLabel.frame = CGRectMake(132, 451, 61, 21);
_seconds.frame = CGRectMake(220, 393, 35, 50);
_secondsLabel.frame = CGRectMake(203, 451, 68, 21);
} if (UIInterfaceOrientationIsLandscape(orientation) && IS_IPHONE_5) {
_Logo.frame = CGRectMake(221, 20, 127, 150);
_timeLabel.frame = CGRectMake(141, 178, 286, 21);
_years.frame = CGRectMake(87, 221, 35, 50);
_yearsLabel.frame = CGRectMake(83, 279, 42, 21);
_months.frame = CGRectMake(162, 221, 35, 50);
_monthsLabel.frame = CGRectMake(150, 279, 58, 21);
_days.frame = CGRectMake(234, 221, 35, 50);
_daysLabel.frame = CGRectMake(232, 279, 39, 21);
_hours.frame = CGRectMake(308, 221, 35, 50);
_hoursLabel.frame = CGRectMake(302, 279, 46, 21);
_minutes.frame = CGRectMake(385, 221, 35, 50);
_minutesLabel.frame = CGRectMake(372, 279, 61, 21);
_seconds.frame = CGRectMake(466, 221, 35, 50);
_secondsLabel.frame = CGRectMake(449, 279, 68, 21);
} else {
_Logo.frame = CGRectMake(177, 20, 127, 150);
_timeLabel.frame = CGRectMake(97, 178, 286, 21);
_years.frame = CGRectMake(27, 221, 35, 50);
_yearsLabel.frame = CGRectMake(23, 279, 42, 21);
_months.frame = CGRectMake(102, 221, 35, 50);
_monthsLabel.frame = CGRectMake(90, 279, 58, 21);
_days.frame = CGRectMake(174, 221, 35, 50);
_daysLabel.frame = CGRectMake(172, 279, 39, 21);
_hours.frame = CGRectMake(248, 221, 35, 50);
_hoursLabel.frame = CGRectMake(242, 279, 46, 21);
_minutes.frame = CGRectMake(325, 221, 35, 50);
_minutesLabel.frame = CGRectMake(312, 279, 61, 21);
_seconds.frame = CGRectMake(406, 221, 35, 50);
_secondsLabel.frame = CGRectMake(389, 279, 68, 21);
}
}
If I comment out the middle bit the app runs fine on the iPhone 5 simulator, but when I use the iPhone 4 simulator & rotate the device the labels go off the screen - this is my reason for needing to detect the device (its fine in portrait mode on both devices as the bottom set of labels dont go to the bottom of the screen).
If I run it as is - the labels & logo display in landscape view even if the device (any device) is in portrait mode/view.
I'm guessing the problem is some form of 'fall through' or logic error with my setup/plan but I cannot think of another way to word/program this at this point.
Thanks
I think you want the code in the else block to run only for 3.5 inches devices in landscape mode right?
In that case you need to add an else before the second if, otherwise the third block of code after the else statement will always run and if I understood correctly, it will create a landscape layout, regardless of the orientation you are passing in.