Table Cell not selectable after rotation - ios

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.

Related

iOS 11.2 custom navigation bar infinite loop

Since the release of IOS 11.2 my app is encountering an infinite loop when pushing a view controller whose navigation controller has a custom navigation bar height. Did someone find the solution for this problem? Thanks.
-(void)layoutSubviews{
[super layoutSubviews];
float height = 42.5;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
height = 48;
}
imageView.frame = CGRectMake(0, 0, [[UIScreen mainScreen]bounds].size.width, height);
if(UI_USER_INTERFACE_IDIOM() ==UIUserInterfaceIdiomPad){
if(#available(iOS 11.0,*)){
self.frame =CGRectMake(0, 20,[[UIScreen mainScreen]bounds].size.width, 55); // this line provoke the infinite loop
for(UIView *aView in self.subviews){
if([NSStringFromClass([aView class]) isEqualToString: #"_UINavigationBarContentView"]){
aView.frame = CGRectMake(0, 10, aView.frame.size.width, aView.frame.size.height);
}
if([NSStringFromClass([aView class]) isEqualToString: #"_UIBarBackground"]){
aView.frame = CGRectMake(0, 0, aView.frame.size.width, self.frame.size.height );
}
}
}
}
}
I also had the same problem.
I solved by removing this
frame.size.height = customHeight
from layoutSubviews and then adding this
override var frame: CGRect {
get {
return CGRect(x: 0, y: 0, width: super.frame.width, height: customHeight)
}
set (value) {
super.frame = value
}
}
to my UINavigationBar subclass.
I left all other code in layoutSubviews as it was before. (nb)

UIScrollView keep buttons in fixed position

I am using UIScrollView for pinch zooming the image the code I am using is like this
CGRect fullScreenRect=[[UIScreen mainScreen] applicationFrame]; //Full Screen
UIScrollView *scroll = [[UIScrollView alloc] initWithFrame:fullScreenRect];
scroll.backgroundColor = [UIColor clearColor];
scroll.delegate = self;
scroll.contentSize = _imageView.frame.size;
[scroll addSubview:_imageView];
scroll.minimumZoomScale = 1.0;
scroll.maximumZoomScale = 5.0;
[scroll setZoomScale:scroll.minimumZoomScale];
self.view = scroll;
[scroll addSubview:_screenShotButton];
[scroll addSubview:_resolutionButton];
-(void)aligementTheControlBasedOnOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
bool ipad = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
if (ipad) {
if(UIInterfaceOrientationIsLandscape(toInterfaceOrientation))
{
_imageView.frame = CGRectMake(142, 114, 740, 555);
if ([self.resoultion isEqualToString:#"Default"]) {
_imageView.frame = CGRectMake(142, 114, 740, 555);
}
else if([self.resoultion isEqualToString:#"4:3"])
_imageView.frame = CGRectMake(142, 114, 740, 555);
else if([self.resoultion isEqualToString:#"16:9"])
_imageView.frame = CGRectMake(142, 114, 740, 416);
self.screenShotButton.frame = CGRectMake(794, 667, 55, 55);
self.resolutionButton.frame = CGRectMake(857, 667, 55, 55);
}
else
{
_imageView.frame = CGRectMake(64, 238, 640, 480);
if ([self.resoultion isEqualToString:#"Default"]) {
_imageView.frame = CGRectMake(64, 238, 640, 480);
}
else if([self.resoultion isEqualToString:#"4:3"])
_imageView.frame = CGRectMake(64, 238, 640, 480);
else if([self.resoultion isEqualToString:#"16:9"])
_imageView.frame = CGRectMake(64, 238, 640, 360);
self.screenShotButton.frame = CGRectMake(578, 749, 55, 55);
self.resolutionButton.frame = CGRectMake(649, 749, 55, 55);
}
}
}
Based on the resolution user has chosen I am positioning the buttons.
Everything is working fine for me. The problem I am facing is _screenShotButton and _resolutionButton are also moving when I zoom the image. Instead I want to keep the buttons static in the bottom right side of the screen.
Can anyone help me.
You can do it making moving sub view from UIScrollView to super view of scrollview like:
Place/set your button over scroll view (not inside scroll view) as shown here in this snapshot. And also set button constraints (position) with respect to super view of your scrollview.
Here is ref. snapshot of hierarchy of position of each view over each-other.
Do not add your buttons to the scroll view, but to its parent instead.
This part is wrong:
[scroll addSubview:_screenShotButton];
[scroll addSubview:_resolutionButton];
Assuming scroll has a superview (which in your original question it does not), do this instead:
[scroll.superview addSubview:_screenShotButton];
[scroll.superview addSubview:_resolutionButton];
Alternatively, you can pick the order of scroll vs. screenShotButton by replacing -addSubView: by one of the -insertSubview:: methods.

IPad Screen Landscape to Portrait Conversion used Xib files with programmatically

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.

Animating a UISlider

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

How to build a launcher for my iOS app?

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];
}

Resources