I am developing an Theatre Ticket booking iOS Application. In that I want to display a seat layout so that an user can select the number of seats he wants. so i planned to display it in row wise and column wise inside a table view. Is that suggested? Or any other solutions are there?? Here is my code for displaying the buttons inside a UIScroll view. How can I move further. Also I need to handle click events for those buttons and get information and handle later. I need some ideas for that too... Please suggest me some samples.
- (Void) someMethod {
int x = 20, y = 15, rows = [rowsArr count];
for (int i = 0; i < [rowsArr count]; i++) {
NSDictionary * rowsDict = [rowsArr objectAtIndex:i];
NSArray * seatsarr = [rowsDict valueForKey:#"Seats"];
if (![[rowsDict valueForKey:#"RowDescription"] isEqualToString:#"Way"])
[self chapterCreationwithtitle:[NSString stringWithFormat:#"%#", [rowsDict valueForKey:#"RowDescription"]]
withChapterTag:tag + i
andXvalue:x andYvalue:y];
y = y + thumb_incrementY;
if (i == rows) { // (main_scroll.frame.size.width-thumb_incrementX))
x = x + thumb_incrementY;
x = 40;
index1++;
rows = (rows + [rowsArr count]);
}
strSeatDes = [[NSMutableArray alloc] init];
int seats = [seatsarr count];
for (int j = 1; j <= [seatsarr count]; j++) {
NSLog(#"index %d", index2);
NSDictionary * seatsDict = (NSDictionary *)[seatsarr objectAtIndex:j - 1];
[strSeatDes addObject:[NSString stringWithFormat:#"%#", [seatsDict valueForKey:#"SeatDescription"]]];
if (![[seatsDict valueForKey:#"isPassage"] boolValue])
[self seatsCreationwithtitle:[NSString stringWithFormat:#"%#", [seatsDict valueForKey:#"SeatDescription"]] withSeatsTag:tag2 + j andXvalue:xx andYvalue:yy];
xx = xx + thumb_incrementX;
NSLog(#"tag seat:%d", tag2 + j);
if (j == seats) {
yy = yy + thumb_incrementY;
xx = 80;
index2++;
tag2 = tag2 + 100;
seats = (seats + [seatsarr count]);
}
}
NSLog(#"%d", [strSeatDes count]);
main_scroll.contentSize = CGSizeMake(([seatsarr count] + 2) * thumb_incrementX + 110, ([rowsArr count] + 2) * thumb_incrementY);
}
} /* someMethod */
- (void) chapterCreationwithtitle:(NSString *)title withChapterTag:(NSInteger)tags andXvalue:(NSInteger)x andYvalue:(NSInteger)y {
chapter_button = [UIButton buttonWithType:UIButtonTypeCustom];
chapter_button.frame = CGRectMake(x, y, button_width, button_height);
chapter_button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
[chapter_button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[chapter_button setTitle:title forState:UIControlStateNormal];
chapter_button.titleLabel.font = [UIFont boldSystemFontOfSize:16];
[chapter_button setShowsTouchWhenHighlighted:YES];
[chapter_button setAutoresizingMask:UIViewAutoresizingFlexibleTopMargin];
[chapter_button setBackgroundColor:[UIColor darkGrayColor]];
[chapter_button setTag:tags];
// [chapter_button addTarget:self action:NSSelectorFromString(#"getAction:") forControlEvents:UIControlEventTouchUpInside];
[self.main_scroll addSubview:chapter_button];
}
- (void) seatsCreationwithtitle:(NSString *)title withSeatsTag:(NSInteger)tags andXvalue:(NSInteger)x andYvalue:(NSInteger)y {
seats_button = [UIButton buttonWithType:UIButtonTypeCustom];
seats_button.frame = CGRectMake(x, y, button_width, button_height);
seats_button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
[seats_button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[seats_button setTitle:title forState:UIControlStateNormal];
seats_button.titleLabel.font = [UIFont boldSystemFontOfSize:16];
[seats_button setShowsTouchWhenHighlighted:YES];
[seats_button setAutoresizingMask:UIViewAutoresizingFlexibleTopMargin];
[seats_button setBackgroundColor:[UIColor colorWithRed:0.09375 green:0.09765 blue:0.02734 alpha:0.4]];
[seats_button setTag:tags];
[seats_button addTarget:self action:NSSelectorFromString(#"getAction:") forControlEvents:UIControlEventTouchUpInside];
// main_scroll.contentSize = CGSizeMake(x+50, y+50);
[self.main_scroll addSubview:seats_button];
}
If I understand you correctly, you want users to view the seats as they are laid out in the theatre, and to highlight one or more seats in order to book them.
If this was me, I would not use a UITableView. I think in iOS tables are actually more for displaying lists than two dimensional information. However, it can be done - basically you make your own custom cell which is split in to columns. Some code here https://github.com/AlanQuatermain/AQGridView might be useful.
Personally I would think about maybe just having a grid of UIButton controls instead. It depends on how many seats there are, and if they fit on to a single screen.
Related
I have 7 buttons on my storyboard, I have associated a tag number to each of the button. And all the buttons are hooked up to a single IBAction.
In my action method I have a switch statement like switch ([sender tag])
which run the appropriate action according to the tag. This is all working.
But I want to add a functionality where selected button is highlight and rest of them in normal state.
You can create property with tags:
#property (nonatomic, strong) NSArray *tags;
Somewhere (for example, in viewDidLoad) initialize it with values used in storyboard:
tags = #[#1, #2, #3, #4, #5]
And select buttons using this tags
- (IBAction)buttonPressed:(UIButton *)sender {
for (int i = 0; i < tags.count; i++) {
UIButton *button = [self.view viewWithTag:tags[i]];
button.selected = (button.tag == sender.tag);
}
}
Or you can create IBOutlets for every 7 buttons and create array for it.
array = #[outlet1, ..., outlet7]
And select buttons using outlets
- (IBAction)buttonPressed:(UIButton *)sender {
for (int i = 0; i < array.count; i++) {
UIButton *button = array[i];
button.selected = (button.tag == sender.tag);
}
}
Hope this can give you some idea:
- (void)setupButtons {
for (int i = 0; i < 7; i++) {
CGFloat width = self.view.frame.size.width / 7;
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(i * width, 100, width, 30)];
[self.view addSubview:button];
button.tag = 1000 + i;
[button setTitle:[NSString stringWithFormat:#"%d", i] forState:UIControlStateNormal];
button.backgroundColor = [UIColor redColor];
[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[button setTitleColor:[UIColor whiteColor] forState:UIControlStateSelected];
[button addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchDown];
if (i == 0) {
// default first button selected
button.selected = YES;
}
}
}
- (void)buttonClicked:(UIButton *)sender {
for (int i = 0; i < 7; i++) {
UIButton *button = [self.view viewWithTag:(1000+i)];
button.selected = (button.tag == sender.tag);
}
}
I seem to have a problem in my Objective C iOS app where I am creating multiple buttons depending on the amount of objects in an array. I know Swift, so I replicated the logic into Swift, and it worked. Yet in Objective C, I am unable to see the text of the button (after I remove the for loop) or create multiple buttons. For example, I have an array full of three names. I would like to create a button for each name with the title set to the corresponding name. So far, I have this:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableArray *ages = [[NSMutableArray alloc] init];
for (int i = 0; i > 10; i++) {
[ages addObject:[NSString stringWithFormat:#"%i", i]];
}
UIScrollView *scrollView= [[UIScrollView alloc]initWithFrame:self.view.frame];
scrollView.delegate= self;
self.automaticallyAdjustsScrollViewInsets= NO;
scrollView.backgroundColor= [UIColor clearColor];
scrollView.scrollEnabled= YES;
scrollView.userInteractionEnabled= YES;
[scrollView setShowsHorizontalScrollIndicator:NO];
[scrollView setShowsVerticalScrollIndicator:NO];
CGFloat xValue = 0;
for(int x=0; x > ages.count; x++){
UIButton *button= [[UIButton alloc] initWithFrame:CGRectMake(xValue ,0 , 172 ,65)];
UIColor *buttonOutline = [[UIColor redColor] CGColor];
button.layer.borderColor = [buttonOutline CGColor];
button.layer.backgroundColor = [[UIColor clearColor] CGColor];
button.layer.borderWidth = 1.0;
button.layer.cornerRadius = 6.0;
[button.titleLabel setFont:[UIFont fontWithName:#"Helvetica" size:13.0]];
button.titleLabel.text = [ages objectAtIndex:x];
[button addTarget:self action:#selector(test:) forControlEvents:UIControlEventTouchUpInside];
[scrollView addSubview:button];
NSLog(#"Button Added");
xValue = button.frame.size.width + 40;
}
scrollView.contentSize = CGSizeMake(xValue, 65);
[self.view addSubview:scrollView];
}
- (void)test:(UIButton*)sender{
NSLog(#"Clicked %#", sender.titleLabel.text);
}
#end
If anyone sees anything wrong with this code, please point it out!
Thanks,
Arnav K.
I found four problems (there may be others) that stop this working correctly:
1) The for loop bound when setting up the ages array is incorrect.
2) The for loop bound when creating the buttons is incorrect.
3) You are setting the buttonOutline colour incorrectly.
4) xValue is being updated incorrectly.
Here is the viewDidLoad method after the changes have been made:
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableArray *ages = [[NSMutableArray alloc] init];
for (int i = 0; i < 10; i++) { // UPDATED
[ages addObject:[NSString stringWithFormat:#"%i", i]];
}
UIScrollView *scrollView= [[UIScrollView alloc]initWithFrame:self.view.frame];
scrollView.delegate= self;
self.automaticallyAdjustsScrollViewInsets= NO;
scrollView.backgroundColor= [UIColor clearColor];
scrollView.scrollEnabled= YES;
scrollView.userInteractionEnabled= YES;
[scrollView setShowsHorizontalScrollIndicator:NO];
[scrollView setShowsVerticalScrollIndicator:NO];
CGFloat xValue = 0;
for(int x=0; x < ages.count; x++){ // UPDATED
UIButton *button= [[UIButton alloc] initWithFrame:CGRectMake(xValue ,0 , 172 ,65)];
UIColor *buttonOutline = [UIColor redColor]; // UPDATED
button.layer.borderColor = [buttonOutline CGColor];
button.layer.backgroundColor = [[UIColor clearColor] CGColor];
button.layer.borderWidth = 1.0;
button.layer.cornerRadius = 6.0;
[button.titleLabel setFont:[UIFont fontWithName:#"Helvetica" size:13.0]];
button.titleLabel.text = [ages objectAtIndex:x];
[button addTarget:self action:#selector(test:) forControlEvents:UIControlEventTouchUpInside];
[scrollView addSubview:button];
NSLog(#"Button Added");
xValue += button.frame.size.width + 40; // UPDATED
}
scrollView.contentSize = CGSizeMake(xValue, 65);
[self.view addSubview:scrollView];
}
I have marked the four lines I changed with a UPDATED comment so you can compare them to the original.
EDIT
To change the text and text colour use the following:
[button setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
[button setTitle:[ages objectAtIndex:x] forState:UIControlStateNormal];
and remove this:
button.titleLabel.text = [ages objectAtIndex:x];
You need to do this because you can set different text for the different states of the button and this is all handled automatically for you.
What I am trying to do is align views in a grid that are in an array. I have created the views and the array.
for (int i = 0; i < [directoryContents count]; i++){
UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(0,0,100,120)];
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchDown];
[button setTitle:#"Show View" forState:UIControlStateNormal];
button.frame = CGRectMake(0, 0, 100, 100);
button.accessibilityIdentifier = [directoryContents objectAtIndex:i];
UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(0, 100, 100, 20)];
label.textAlignment = NSTextAlignmentCenter;
label.text = [directoryContents objectAtIndex:i];
[containerView addSubview:button];
[containerView addSubview:label];
[self.view addSubview:containerView];
[_containerViewArray addObject:containerView];
}
[self layoutViews:_containerViewArray inView:self.view];
What I have working is aligning them next to each other the problem I am having is I need to have them wrap down instead of going off the edge. What I am doing to algin them is this
- (void)layoutViews:(NSArray *)views inView:(UIView *)contentView
{
NSInteger overallWidth = 0;
for ( UIView *view in views ) {
overallWidth += view.frame.size.width;
}
CGSize contentSize = contentView.frame.size;
CGFloat startOffset = (contentSize.height - overallWidth)/2.0;
CGFloat offset = startOffset;
for ( UIView *view in views ) {
CGRect frame = view.frame;
frame.origin.x = offset;
view.frame = frame;
offset += view.frame.size.width;
}
}
If we assumed that we have an array of sections (your views) and you need to layout 3 item per row the view has size 98*98 and spacing 6.5px horizontally and 8px Vertically
for (int i = 0; i< [sectionsArray count]; i++) {
int row = (int)i/3;
int col = i%3;
float x = 6.5 + (104.5*col);
float y = 8 + (106*row);
UIView *sectionView = [[UIView alloc] initWithFrame:CGRectMake(x, y, 98, 98)];
sectionView.backgroundColor = [UIColor clearColor];
//button
UIButton *sectionButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[sectionButton setTintColor:[UIColor grayColor]];
sectionButton.frame = CGRectMake(0, 0, 98, 98);
sectionButton.tag = i+100;
[sectionButton addTarget:self action:#selector(showSectionDetail:) forControlEvents:UIControlEventTouchUpInside];
[sectionView addSubview:sectionButton];
//adding title
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 75, 98, 20)];
titleLabel.textAlignment = UITextAlignmentCenter;
titleLabel.backgroundColor=[UIColor clearColor];
titleLabel.font=[UIFont fontWithName:#"Helvetica" size:14];
titleLabel.textColor = [UIColor colorWithRed:241.0/255.0 green:124.0/255.0 blue:22.0/255.0 alpha:1.0];
titleLabel.text = [[sectionsArray objectAtIndex:i] objectForKey:#"Title"];
[sectionView addSubview:titleLabel];
[titleLabel release];
[scroll addSubview:sectionView];
[sectionView release];
}
int numberOfRows;
if ([sectionsArray count]/3.0f == 0) {
numberOfRows = [sectionsArray count]/3;
}else{
numberOfRows = [sectionsArray count]/3 +1;
}
scroll setContentSize:CGSizeMake(320, numberOfRows*106);
Here's what I used until the UICollectionView was released, easy to modify to accommodate for how many rows you want in the grid, and the size of the views.
NSUInteger buttonWidth = 100;
NSUInteger buttonHeight = 100;
NSUInteger space = 5;
float scrollContentY = (ceilf((float)imageNames.count / 3.0f) * (buttonHeight + space));
[myArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
int row = idx / 3;
int column = idx % 3;
UIView *view = [UIView new];
[view setBackgroundColor:[UIColor redColor]];
view.frame = CGRectMake((buttonWidth + space) * column + space, (buttonHeight + space) * row + space , buttonWidth, buttonHeight);
[view setTag:(NSInteger)idx];
[self.scrollView addSubview:view];
[self.scrollView setContentSize:CGSizeMake(self.scrollView.frame.size.width, scrollContentY)];
}];
Mind you, this might not be advisable if you have a large array to enumerate because this doesn't have any kind of reusable views. It will alloc/init a view for every item in the array.
I'm trying to add images over a ScrollView. I have the x and y point in a plist file and they are called by an enum.
enum {
kLogoImage = 1,
kNewLogoImage,
};
#implementation
- (void) _setupStaticViews
{
UIButton *image = [UIButton buttonWithType:UIButtonTypeCustom];
[image setBackgroundImage:[UIImage imageNamed:#"logo.png"] forState:UIControlStateNormal];
[image addTarget:self action:#selector(_addContactButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
image.frame = CGRectMake(0.0 ,0.0, 150.0, 150.0);
image.tag = kLogoImage;
[_mapImageView addSubview:image];
_staticViews = #[image];
UIButton *image2 = [UIButton buttonWithType:UIButtonTypeCustom];
[image2 setBackgroundImage:[UIImage imageNamed:#"Time Bakground.png"] forState:UIControlStateNormal];
[image2 addTarget:self action:#selector(_addContactButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
image2.frame = CGRectMake(0.0 ,0.0, 250.0, 150.0);
image2.tag = kNewLogoImage;
[_mapImageView addSubview:image2];
_staticViews = #[image2];
for ( UIView *view in _staticViews ) {
CGPoint point = [self _basePositionForView:view];
CGRect frame = view.frame;
frame.origin = point;
view.frame = frame;
}
}
If I have only image showing, it works fine. But I need to add more than one and adding the second one causes the first one to be at xy point 0,0, and Image2 isn't visible.
How would I go about adding another image?
- (CGPoint) _basePositionForView:(UIView *)view {
NSString *key = [NSString stringWithFormat:#"%d", view.tag];
NSString *stringValue = [_coordinates objectForKey:key];
NSArray *values = [stringValue componentsSeparatedByString:#":"];
if ( [values count] < 2 ) return CGPointZero;
CGPoint result = CGPointMake([[values objectAtIndex:0] floatValue], [[values objectAtIndex:1] floatValue]);
return result;
}
I noticed that you first make
_staticViews = #[image];
and later
_staticViews = #[image2];
Don't you rather mean to have
_staticViews = #[image, image2];
?
You should iterate and change x accordingly in the frame:
for ( int iterator=0; iterator< [[_staticViews subviews] count]; iterator++){
...
current_image.frame = CGRectMake(YOUR_IMG_WIDTH * iterator ,0.0, YOUR_IMG_WIDTH, 150.0);
...}
I have this code and I want to have my button as a square, and also under the navigation bar,would you plase help me
Thanks in advance!
I want to have my button as a square
- (void)viewDidLoad
{
[super viewDidLoad];
int rows = 13, columns = 4;
UIView *buttonView = [[UIView alloc] initWithFrame:CGRectMake(0.f, 0.f, 70*columns, 70*rows)];
for (int y = 0; y < rows; y++) {
for (int x = 0; x < columns; x++) {
UIButton * button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(70 * x, 28 * y, 70, 28);
[button addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[buttonView addSubview: button];
}
}
// Center the view which contains your buttons
CGPoint centerPoint = buttonView.center;
centerPoint.x = self.view.center.x;
buttonView.center = centerPoint;
[self.view addSubview:buttonView];
}
-(void)buttonPressed:(UIButton *)button
{
NSLog(#"button %u -- frame: %#", button.tag, NSStringFromCGRect(button.frame));
}
Edit 2
my error when I using border
[button.layer setBorderWidth:1.0];
[button.layer setBorderColor:[UIColor blackColor]];
Define an integer variable and set this as button title
int rows = 13, columns = 4;
int number=1;
UIView *buttonView = [[UIView alloc] initWithFrame:CGRectMake(0.f,44, 70*columns, 70*rows)];
for (int y = 0; y < rows; y++) {
for (int x = 0; x < columns; x++) {
UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(75 * x, 75 * y, 70, 70);
button.backgroundColor=[UIColor redColor];
[button setTitle:[NSString stringWithFormat:#"%d",number] forState:UIControlStateNormal];
button.tag=number;
[button addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[buttonView addSubview: button];
number++;
}
}
Hope this will help you to move to next screen. Button.tag gives the exact button you have selected.
You are setting your button of size 70x28, so if you want a button 70x70, you have to change button.frame = CGRectMake(70*x, 70*y, 70, 70), this way you will have square buttons.
Also, are you sure this is a NavigationBar or just a Toolbar? If you use NavigationController which uses navigationBar, Apple's own SDK will not allow you to easily draw over it.
In any case in your case, just start drawing your buttons from y = 44 down and you won't have buttons overlap the toolbar.
Try this
int rows = 13, columns = 4;
UIView *buttonView = [[UIView alloc] initWithFrame:CGRectMake(0.f,44, 70*columns, 70*rows)];
for (int y = 0; y < rows; y++) {
for (int x = 0; x < columns; x++) {
UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(75 * x, 75 * y, 70, 70);
button.backgroundColor=[UIColor redColor];
[button addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[buttonView addSubview: button];
}
}
// Center the view which contains your buttons
CGPoint centerPoint = buttonView.center;
centerPoint.x = self.view.center.x;
buttonView.center = centerPoint;
[self.view addSubview:buttonView];
For using layer property you need to add QuartzCore.framework in your project.