Xcode - insertSubview:atIndex: not working as I expected it to - objective-c

I've been trying to use insertSubview:atIndex: to insert a subview under another one. The problem is that most of the time it's not the view with the higher index that is above, but the view that was added last. I noticed that this works fine if I pick indexes 0 and 1 but in my case one view needs to be at least at the index 12 and the other one needs to be above.
Here is some code as an example:
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(20, 100, 100, 100)];
label.text=#"LABEL";
[label setBackgroundColor:[UIColor whiteColor]];
[self.view insertSubview:label atIndex:13];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.frame=CGRectMake(20, 100, 100, 100);
[btn setBackgroundColor:[UIColor whiteColor]];
[self.view insertSubview:btn atIndex:12];
I know I could insert the label after the button but that wouldn't solve the problem in my case.
What am I doing wrong?
Thank you in advance for your help.

It doesn’t work like the CSS z-index—if a view has k subviews, inserting a view at any index higher than k will have the same effect as adding it at index k, or, in other words, adding it as the last (frontmost) subview. The subviews are maintained as a continuous list, not an arbitrarily-indexed array. In your case, you probably don’t have 14 subviews to start out with, so inserting one view at 13 and another at 12 isn’t having the effect you want.

Related

UIButton not clickable after UITableView scrolled

I have a UITableView which is populated with some cells. I have created a UIButton using the following snippet, it is placed next to one of the section headers.
UIButton *addButton = [UIButton buttonWithType:UIButtonTypeCustom];
[addButton addTarget:self action:#selector(addButtonPressed) forControlEvents:UIControlEventTouchUpInside];
[addButton setBackgroundImage:[UIImage imageNamed:#"add.png"] forState:UIControlStateNormal];
addButton.backgroundColor = [UIColor clearColor];
addButton.frame = CGRectMake(270, 150, 29, 29);
The button is placed and works correctly. However, after the view is scrolled (even slightly - like 1 pixel), the button works once and then ceases to respond. When it fails to respond the action for when it is clicked is not triggered and the button doesn't give the 'depressed' shadow. The rest of the application runs as normal and it does not crash.
This seems odd because after I scroll the button is clickable once more before it stops working. The button is used to insert rows into the table, so after it is pressed there is an extra row, possibly this is breaking the bounds or something?
Button pressed function:
- (void)addButtonPressed {
self.addClientTable.editing = YES;
// First figure out how many sections there are
NSInteger lastSectionIndex = [self numberOfSectionsInTableView:self.addClientTable] - 1;
// Then grab the number of rows in the last section
NSInteger lastRowIndex = [self.addClientTable numberOfRowsInSection:lastSectionIndex];
[self.addClientTable insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:lastRowIndex inSection:lastSectionIndex]] withRowAnimation:UITableViewRowAnimationRight];
self.addClientTable.editing = NO;
}
Where addClientTable is the UITableView.
What could cause a UIButton to stop responding to clicks and where in my scenario would this be caused by?
I am almost sure that your problem is that your button is out of it superview, and you are not using the clip subviews option in your view that contains the button, or in one of it superviews.
Set to true all the views property clip subviews and see if it appears your button. (We expect that the button disappear)
If you provide more code I can try to help you to solve this problem.
-
Reading again your question, another probable problem to it is that you have one view in front of your button. You can test it changing the background of your view, or something like that.

Height of UIScrollView get changed?

I am adding UITableView and UIButton in UIScrollView. button is placed below tableview.
Well, when i select any row from table it add a button on that row and every thing is ok till now, but when i click that row second time it remove button added on it but the problem is that along with removing that button it also scroll my table up and button bellow the table reside on its place ie. it leaves gap between table and button.
my table is reloaded every time when a row is clicked.
code for add UIButtonbelow the UITableView
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
mainTable.frame = CGRectMake(mainTable.frame.origin.x, mainTable.frame.origin.y,
mainTable.frame.size.width,
([menuItemsArray count] * 60) + 380);
[scrollView setContentSize:CGSizeMake(320,([menuItemsArray count] * 60) + 80 + 350)];
reserverBtnBottom = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[reserverBtnBottom setFrame:CGRectMake(20.0f,mainTable.frame.size.height,280, 40)];
[reserverBtnBottom addTarget:self action:#selector(reserveBtnAction) forControlEvents:UIControlEventTouchUpInside];
[reserverBtnBottom setBackgroundImage:[UIImage imageNamed:#"normal.png"] forState:UIControlStateNormal];
[reserverBtnBottom setAlpha:1];
[reserverBtnBottom setTitle:#"Reserve this table" forState:UIControlStateNormal];
[reserverBtnBottom setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[scrollView addSubview:reserverBtnBottom];
rest thing goes here
}
What am i missing?
Thanks in advance.
heightForRowAtIndexPath is a bad place for such calculation, as you are changing a single row state this method might be called once to calculate the new height. When it is called the cell still has an old height value, so does the table.
The button position calculation should be moved to layoutSubviews: method of the table and button superview which is a scrollView in your example. The way it should work is that the superview recalculates all the subviews frames once any of them changes it's frame.
Sometimes instead of overriding the layoutSubviews: the frame calculation is handled with the viewController , that's what you were trying to do but you did it in a wrong way. You'll need to find a better place for the frame calculation if you don't want to override scrollView layoutSubviews:.
If you only need the scrollView to add the button below the table, it would be better from my experience to get rid of the scroll view (at least because you do have scroll view in another scroll view which is Never a good practice) and add the button to the table footerView. The footer view is displayed below the table and scrolls together with it.
After long time i resolve my problem. put this code in viewWillAppear instead heightForRowAtIndexPath-
mainTable.frame = CGRectMake(mainTable.frame.origin.x, mainTable.frame.origin.y,
mainTable.frame.size.width,
([menuItemsArray count] * 60) + 380);
[scrollView setContentSize:CGSizeMake(320,([menuItemsArray count] * 60) + 80 + 350)];
and move my reserveBtnBottom to footer of UITableView.
Thanks to A-Live for his great help.

UILabel Not Released And Wrong Position Display

What I am trying to do is display a label on loading view for first time. When User will tap an object, that label should disappear and three circles should appear on its position. But what is happening is that my label is not hidden when I am trying to release it, as I will be needing it no more. Also it is not present at position I want.
What I have done is:
#interface AnimateCircle : UIViewController
{
UILabel *text;
CALayer *smallCircle1;
CALayer *smallCircle2;
CALayer *smallCircle3;
}
and then declared property for label and synthesized it. Please note that I have added AnimateCircle as subview of a view. So my subview is starting from small circles as indicated in 2nd figure.
In viewDidLoad, I wrote:
text = [[UILabel alloc] initWithFrame:CGRectMake(10, 5, 310, 100)];
text.text = #"Tap the Red Button To Start The Timer...!";
text.font = [UIFont fontWithName:#'SnellRoundHand-Bold" size:8];
[self.view addSubview:text];
[text release];
At tap Gesture, I call a method in which I release my label text to hide it.
[text removeFromSuperView];
and draw three circles at its position. Just showing position...
smallCircle1.frame = CGRectMake(100, 15, 30, 30);
smallCircle2.frame = CGRectMake(140, 15, 30, 30);
smallCircle3.frame = CGRectMake(180, 15, 30, 30);
Failed after struggling for 2 hours. Please can someone tell me that what am I missing? Thanks a lot...
You must actually add the 3 circles to the view.
Use self.view.layer addSublayer:.

Question on UIScrollView and UIImageViews

I am making an iPad app that will display six, side by side UIImageViews at once (3 on each line). I want it to be scrollable so I can display up to 15. So its basically like 5 rows of 3 UIImageViews.
I assume I will have to position the UIImageViews programatically and not using IB - is this right? If so, what do I put their positions as? So I know the positions for the first 6 UIImageViews, but what about the rest? And how do I make them appear on UIScrollView in a scrollable manner?
Is there a way to do that using IB too - or is it done all programatically?
Thank you for your help,
You need to position them in code
You can position a UIImageView like so:
UIImageView *image = [[UIImageView alloc] init];
image.frame = CGRectMake(0, 0, 50, 50);
[myScrollView addSubview: image];
This creates an image view and places it at 0, 0 in the scrollview with a width and height of 50.
You need to positon your elements like so, then when you get to the elements that will be offscreen you keep going like:
UIImageView *image1 = [[UIImageView alloc] init];
image1.frame = CGRectMake(0, 1100, 50, 50);
[myScrollView addSubview: image1];
This positions the element offscreen in the scrollview
to make the scollview scroll you need to set the contentSize of the scrollview to be bigger than the screen ie. the size of all your elements together
So if you have 6 images that are 500 pixels in height the height on your contentSize will be 6 x 500
To set the content size:
myScrollView.contentSize = CGSizeMake(768, 3000);
No its not necessary to create images by code you can do it by making a view controller and in its xib add three UIImageView as you want and then use a page control with UIScrollView and for more detail follow the tutorial -
http://www.edumobile.org/iphone/iphone-programming-tutorials/pagecontrol-example-in-iphone/

Resize UITableViewCell content when delete button shows up

Is there any way to use autoresizing masks to move my content so that the delete button doesn't cover it up? Googling has told me that I need to set an autoresizing mask of UIViewAutoresizingFlexibleRightMargin on my subview. It seems to me like UIViewAutoresizingFlexibleWidth would actually make more sense; though I've tried them both and neither works.
The view that I am trying to shrink is just a label that is a subview of the cell's contentView. I am unsure if the contentView itself automatically resizes when the delete button shows up; but it seems like it isn't; otherwise my autoresizing mask should have worked.
If the presence of the delete button doesn't cause any views to be resized; is there anyway that I can do this manually?
You should use UIViewAutoresizingFlexibleLeftMargin.
Here's why. You want your contents to move to the left, basically making it seem like the delete button is pushing the contents to the left, out of it's way. flexibleLeftMargin basically means your UILabel will stay fixed to the right side of your contentView. The reason you want this, is because the delete button actually causes your contentView to shrink it's width.
The autoresizingmask of your UILabel refers to how it behaves inside the contentView, not the cell.
Give it a try, it should work.
This question is really old but I feel I should answer this anyway since I just found the solution myself.
Only the cell's ContentView gets resized with the confirmation button is shown. If you don't add your views (labels, imageviews, etc...) to the cell.contentView instead of adding them to the cell directly then they won't be resized when the contentView is resized. In my case, I was adding it to the cell directly.
So, instead of doing something like:
UILabel *nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(5, 5, width-10, 20)];
[nameLabel setFont:[UIFont boldSystemFontOfSize:16]];
[nameLabel setHighlightedTextColor:[UIColor whiteColor]];
[nameLabel setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
[nameLabel setTag:101];
[cell addSubview:nameLabel];
[nameLabel release];
you should do:
UILabel *nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(5, 5, width-10, 20)];
[nameLabel setFont:[UIFont boldSystemFontOfSize:16]];
[nameLabel setHighlightedTextColor:[UIColor whiteColor]];
[nameLabel setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
[nameLabel setTag:101];
[[cell contentView] addSubview:nameLabel]; // <<--- note the change in this line!
[nameLabel release];
Hope this helps others who stumble upon this issue.
I am using iOS 7, I got the same issue. I am using a separate xib for the UITableViewCell with auto layout enabled, so just added one more constraint to the label so that it will have a fixed gap on its right side.