I have three button in my view and sometimes I should hide one button or two button because I don't use them; I can insert them in a toolbar or in a subview but I don't know a fast solution to fair distance buttons. For example:
Three buttons:
Two button:
One button:
is there a fast solution to distance button in a dynamic solution, without take their position?
float width = 768.0f;
int numberOfButtons = 3;
float buttonWidth = 100.0f;
float buttonHeight = 40.0f;
float spaceX = floorf((width - (numberOfButtons * buttonWidth)) / (numberOfButtons + 1));
float x,y,w,h;
for (int i = 0; i < numberOfButtons; i++)
{
x = spaceX + (spaceX * i);
y = 100.0f;
w = buttonWidth;
h = buttonHeight;
UIButton * b = [[UIButton alloc] initWithFrame:CGRectMake(x,y,w,h)];
[self.view addSubview:b];
}
Where width is the gray view.
I would use a UICollectionView. It would allow you to dynamically add and remove buttons and it would handle all appropriate layout.
Related
There is the question: I set a custom view named ZHLockView. I put it in the storyboard and I set the constraints. But I can't get the correct width in - (id)initWithCoder:(NSCoder *)aDecoder, it is always 320, what should I do to get the correct width?
Last I know in the - (void)layoutSubviews, I can get the right width, but it will going twice. Is there a better idea?
See, you're getting width 320 because your view is of that size on storyboard.
If the width of the view is equal to superview, which is indeed again equal to width of device, you can use following code to get width of view at anytime and dont need to worry about where to write.
Swift :-
CGFloat width = CGRectGetWidth(UIScreen.mainScreen.bounds);
CGFloat height = CGRectGetHeight(UIScreen.mainScreen.bounds);
Objective-C :-
CGFloat width = CGRectGetWidth([[UIScreen mainScreen] bounds]);
CGFloat height = CGRectGetHeight([[UIScreen mainScreen] bounds]);
Hope you understood and it helps you.. :)
the code is here
objc
#define KScreenWidth [UIScreen mainScreen].bounds.size.width
CGFloat height = 0;
CGFloat margin = (KScreenWidth - columnCount * btnW) / (columnCount + 1);
for (int i = 0; i < btnCount; i++) {
int row = i / columnCount;
int column = i % columnCount;
CGFloat btnX = margin + column * (btnW + margin);
CGFloat btnY = row * (btnW + margin);
height = btnH + btnY;
ZHButtonView *button = [[ZHButtonView alloc] initWithFrame:CGRectMake(btnX, btnY, btnW, btnH)];
button.userInteractionEnabled = NO;
button.currentIndex = i;
[button setBackgroundImage:[UIImage imageNamed:#"gesture_node_normal"] forState:UIControlStateNormal];
[button setBackgroundImage:[UIImage imageNamed:#"gesture_node_highlighted"] forState:UIControlStateSelected];
[self addSubview:button];
}
The view will be load with the value in the xib at the first start, next when the autolayout engine makes the first pass, it will be set to a new value according to the constraints set.
Why would you need to know the size? Autolayout is made to do not care about it.
-layoutSubviews, -viewWillLayout, -viewDidLayout are called when the layout engine needs a update, that could means Different times before displaying your view.
I would like to add buttons to an UIView. The number of buttons varies from view to view.
I want to achieve the following:
I tried to add the Buttons (in a foreach construct) like this:
UIButton *but=[UIButton buttonWithType:UIButtonTypeRoundedRect];
but.frame= CGRectMake(200, 15, 15, 15);
[but setTitle:#"Ok" forState:UIControlStateNormal];
[but addTarget:self action:#selector(buttonAction) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:but];
But I don't know how to calculate the CGRectMake when it comes to an new line. How can I check the end of the line (UIView)? Or is it kinda stupid to add Buttons like this?
Thanks
Florian
You need to add calculate buttons size after you set the title. Then keep track of the current X and Y of the previous buttons and figure out if the newly created button can fit on the current "line". Otherwise go to the next one.
I suggest you to look at existing components and see how they do it, below are a couple links.
https://github.com/domness/DWTagList
https://github.com/andreamazz/AMTagListView
With the following code , you can place multiple buttons in one row as long as their total width and the gap is smaller then the view's width.
UIView *view = nil;
NSArray *allBtns = nil;
float viewWidth;
float currentY = 0;
float currentX = 0;
float btnGapWidth = 10.0;
float btnGapHeight = 2.0;
for (UIButton *btn in allBtns) {
CGRect rc = btn.frame;
BOOL shouldAddToNewLine = viewWidth - currentX - btnGapWidth < rc.size.width ? YES : NO;
if (shouldAddToNewLine) {
rc.origin = CGPointMake(0, currentY + rc.size.height + btnGapHeight);
currentX = 0;
currentY += rc.size.height + btnGapHeight;
} else {
//another row
rc.origin = CGPointMake(currentX + rc.size.width + btnGapWidth, currentY);
currentX += rc.size.width + btnGapWidth;
}
btn.frame = rc;
[view addSubview:btn];
}
I've got a UITableView and I want to add a button just underneath the table. The table is bigger than the screen so to get to the button, I need to scroll down to it. The problem is, the screen will scroll to just above where the button is. So I can drag the screen slightly and the button is visible but when I let go, the screen springs back and I can't get to the button.
The button is set up as follows
for(int i = 0; i < [buttonArray count]; i++)
{
UIButton *but = [buttonArray objectAtIndex:i];
float xPosition = but.frame.origin.x;
float xGap = (self.view.frame.size.width - (but.frame.size.width)*2)/3;
if ((i % 2 == 0) && (i < [buttonArray count] - 1))
{
xPosition = xGap;
}
else if ((i % 2 == 1) && (i < [buttonArray count] - 1))
{
xPosition = (xGap * 2) + but.frame.size.width;
}
else
{
xPosition = (self.view.frame.size.width - but.frame.size.width)/2;
}
//Add space between row of buttons
if(i > 0)
{
if(i % 2 == 0)
{
yPosition+=but.frame.size.height;
CGRect screenRect = [[tableView superview] bounds];
//Add extra space between row of buttons
float fGap = (screenRect.size.height / 100.0) * 4.5;
yPosition+=fGap;
}
}
CGRect rect = CGRectMake(xPosition, yPosition, but.frame.size.width, but.frame.size.height);
but.frame = rect;
[but addTarget:self action:#selector(genericMethod:) forControlEvents:UIControlEventTouchUpInside];
CGRect screenRect = [self.view bounds];
CGFloat fHeight = screenRect.size.height;
float fMargin = (fHeight / 100.0) * 0.8;
but.titleEdgeInsets = UIEdgeInsetsMake(0, 0, fMargin, 0);
[tableView addSubview:but];
}
}
So I go through an array of buttons (only one button in the array in my current case) and set up the frames and position them into columns and add it as a subview to the tableView. Things I've tried are:
Increase the table footer size. This just makes the gap between the table and button increase and I still can't scroll down as far as the button.
Add the button to the footer. This kind of worked. I could get to the button, but the button was always on screen, not just static below the table.
Add the button to a separate view below the table and add that view to the viewController.view. This didn't work at all and the button wasn't displayed.
Set the tableView.tableFooterView equal to the button. This also kind of worked and I could reach the button but it wouldn't work when there is more than one button in the array above.
You should create a custom view. Inside that view you should add all the buttons created using buttonArray. Now, assign this custom view to tableFooterView.
UIView *customView = [[UIView alloc] initWithFrame:properFrame];
for(int i = 0; i < [buttonArray count]; i++)
{
//...calculation of frame and other stuff
[customView addSubview:but];
}
tableView.tableFooterView = customView;
This should solve your scrolling issue.
If you want to make bottom view as stable,Take a UIView at the bottom
of UITableView.
If you will use TableFooterView,It will be at the end of cell .
I am putting few icons on UITableViewCell. The number of icons can vary from 1 to 6. Icons should not have fixed X position and instead they should be dynamically placed considering the cell space. So if there are 3 icons they should look placed centric to the cell. Also, the icon spacing should also vary. For instance when it is 6 icons all of them will be placed with less margins in between and when there are 3 then margin will be more and so will be the X position.
Please suggest some quick way to calculate this frame. I am running the app both on iOS 6 and iOS 7.
This is what I have tried by far but this does not seems to work well with icon count variation. Also, in between space is not dynamic with this.
int maxIconTypes = 6;
CGFloat innerPadding = ([self isIOS7]) ? 15.0f : 9.0f;
CGRect adjustedBoundsIOS6 = [self bounds];
CGFloat adjustedWidth = ([self isIOS7]) ? self.bounds.size.width : adjustedBoundsIOS6.size.width;
CGFloat xOrigin = innerPadding;
CGFloat iconViewSize = 25.0f;
CGFloat ySpacer = (self.bounds.size.height - iconSize) / 2;
CGFloat xSpacer = ((adjustedWidth - (innerPadding * 2)) - (maxRequestTypes * iconViewSize)) / (maxIconTypes - 1);
for (NSString *icon in iconList) {
UIImageView *anIconView = [[UIImageView alloc] initWithImage:[UIImage icon]];
if (anIconView.image) {
anIconView.frame = CGRectMake(xOrigin + originPadding, ySpacer, anIconView.image.size.width, anIconView.image.size.height);
[self.contentView addSubview:anIconView];
xOrigin += anIconView.frame.size.width + xSpacer;
}
}
However many items you have, the number of spaces is the same if you want equal spacing with half spacing at the start and end:
half width full width half
half width full width full width half
So, you just need to know the full width available and the combined width of the items. A simple multiply (to get the combined width of the items) and subtract (from the full width available) gives you the remaining width for the 'spacers'. Divide by the number of items to get the xSpacer, set the initial xOrigin to xSpacer * 0.5
Here is an example of what Wain is explaining:
//Im doing this in a UIView rather than in a UITableViewCell but idea is the same
int cellWidth = CGRectGetWidth(self.view.bounds);
//num of icons
int iconCount = 6;
//size of icon
int iconSize = 25;
//The max padding we can have
float maxPadding = (cellWidth - (iconSize * iconCount)) / iconCount;
//Our offset
float xOrigin = maxPadding / 2;
//Loooop
for (int i = 0; i < iconCount; i++) {
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(xOrigin, self.view.center.y, iconSize, iconSize)];
xOrigin += (iconSize + maxPadding);
label.backgroundColor = [UIColor blueColor];
[self.view addSubview:label];
}
So I'm about to make an app for iOS in xCode (go figure), and I am curious as to what people would suggest to do here.
My goal is to create a grid of buttons mxn in dimensions. I recently made a tic tac toe game variation where I had an overall 9x9 grid of buttons. It was very tedious work to create each button.
Would there be an easier way to create all these buttons through code?
Use a for loop to create the buttons. May be something of the following sorts to create a buttons for 3X3 grid
CGFloat xAxis,yAxis,bWidth,bHeight;
xAxis = 0.0;
yAxis = 0.0;
bWidth = 150.0;
bHeight = 44.0;
int numberOfRows = 3;
int numberOfColumns = 3;
int number = 1;
for(int i=0;i<numberOfRows;i++)
{
for(int j=0;j<numberOfColumns;j++)
{
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(xAxis, yAxis, bWidth, bHeight)];
button.titleLabel.text = [NSString stringWithFormat:#"%#",number];
number++;
[self.view addSubview:button];
xAxis = xAxis + bWidth + 5.0;
}
xAxis = 0;
yAxis = yAxis + bHeight + 5.0;
}
IBOutletCollections are a good candidate here, if you have a reasonable number of buttons. You can then loop through all of them to apply the same properties.