when I click on button I get only 1 extra view, but I want a the view to be added dynamically on number of click, (like for loop)...Kindly help me with this code, Thanks in Advance,
this is just a part of my code
if (boolVal == true) {
CGRect newFrameC = CGRectMake(_centreView.frame.origin.x, _centreView.frame.origin.y, _centreView.frame.size.width, 50);
CGRect newFrameL1 = CGRectMake(_label2.frame.origin.x, _label2.frame.origin.y+50, _label2.frame.size.width, 50);
_centreView.frame = newFrameC;
_label2.frame = newFrameL1;
boolVal = false;
}else if (boolVal == false){
CGRect newFrameC = CGRectMake(_centreView.frame.origin.x, _centreView.frame.origin.y, _centreView.frame.size.width, 1);
CGRect newFrameL1 = CGRectMake(_label2.frame.origin.x, _label2.frame.origin.y-50, _label2.frame.size.width, 50);
_centreView.frame = newFrameC;
_label2.frame = newFrameL1;
boolVal = true;
}
DummyViewController.m
#import "DummyViewController.h"
#import "ExtraView.h"
#interface DummyViewController ()
#property (nonatomic) unsigned int numberOfExtraViews;
#property (nonatomic, strong) NSMutableArray<ExtraView*>* extraViews;
#property (nonatomic, strong) UILabel* label1;
#property (nonatomic, strong) UILabel* label2;
#end
#implementation DummyViewController
-(void) removeExtraViews{
for (ExtraView* extraView in _extraViews){
[extraView removeFromSuperview];
}
[_extraViews removeAllObjects];
}
-(CGRect) getExtraViewFrame{
CGRect extraViewFrame = _label1.frame;
if (_numberOfExtraViews > 0) {
extraViewFrame = [_extraViews lastObject].frame;
}
extraViewFrame.origin.x += extraViewFrame.size.height;
return extraViewFrame;
}
- (void) addExtraViews{
//[self removeExtraViews];
int numberOfExtraViewsToDraw = _numberOfExtraViews - _extraViews.count;
for (int iterator = 0; iterator < numberOfExtraViewsToDraw; iterator ++){
CGRect extraViewFrame = [self getExtraViewFrame];
ExtraView *extraView = [[ExtraView alloc]initWithFrame:extraViewFrame];
[self.view addSubview:extraView];
[_extraViews addObject:extraView];
}
if (numberOfExtraViewsToDraw > 0) {
CGRect label2Frame = [_extraViews lastObject].frame;
label2Frame.origin.x += label2Frame.size.height;
_label2.frame = label2Frame;
}
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self addExtraViews];
//rest of your code
}
//Use this code in initWithNib/initWithCoder. Don't copy paste the same
-(instancetype)init{
self = [super init];
if (nil != self){
_numberOfExtraViews = 0;
_extraViews = [[NSMutableArray alloc]init];
}
return self;
}
//the function that gets hit when the button is tapped.
- (void) onButtonTap{
_numberOfExtraViews++;
[self.view setNeedsDisplay];
}
Note the following:
I do not understand what the boolVal is, but if it keeps toggling upon the click of the button, you'll never have multiple views.I assumed it toggles, so I havent used it at all.
Use the init code in initWithNib/initWithCoder. Don't copy paste the same. Don't overwrite the given code. Just append to your current init.
In my code onButtonTap is the function that gets hit when the button is tapped.
I've done it by ensuring viewDidLoad method gets hit agin. But I dont think it's necessary. You can also do this:
//the function that gets hit when the button is tapped.
- (void) onButtonTap{
_numberOfExtraViews++;
[self addExtraViews];
}
What has been done:
Let me call what you call as centerView as extraView. There will be many extraViews, so I'll create an array for the same (extraViews).
The count of the number of views is stored in numberOfExtraViews. Initiated to 0 in init.
Whenever the button is tapped, we increase the count and call view's setNeedsDisplay, which in turn hits the viewDidLoad method
In viewDidLoad, we add the extraViews.
Related
I am trying to pass an integer value between UIViewControllers, new to iOS and having problems.
In the UIViewController where the value is being set, there are no problems. But after the value is set NSLog is showing that the value is null in the second UIViewController.
My app is going to use the horizontal slider to determine the length of time in between a UIImage animationDuration in a different UIViewController.
This method is correctly receiving the value from the horizontal slider. I initialized an instance of the "other" UIViewController, imageview.somedata belongs to the other view controller. I know the value is being passed correctly because of the NSLogs below.
- (IBAction) changeButtonPressed:(id)sender {
imageView = [[GTImageView alloc] initWithNibName:#"GTImageView" bundle:nil];
NSLog(#"text value = %#", myTextField);
NSString *textValue = [myTextField text];
int value = [textValue floatValue];
if (value < 0) value = 0;
if (value > 100) value = 100;
mySlider.value = value;
sliderValue = &value;
NSLog(#"sliderValue = %d", *(sliderValue));
myTextField.text = [NSString stringWithFormat:#"%.1d", value];
if ([myTextField canResignFirstResponder]) [myTextField resignFirstResponder];
imageView.someData = *(sliderValue);
NSLog(#"imageView.someData = %d", imageView.someData);
}
This is the top of that implementation file
#import "GTSettingsVC.h"
#import "GTImageView.h"
#import "GTImageView.m"
#interface GTSettingsVC ()
#end
#implementation GTSettingsVC
#synthesize mySlider, myTextField;
#synthesize sliderValue;
That header file
#import "GTImageView.h"
#interface GTSettingsVC : UIViewController
{
IBOutlet UISlider *mySlider;
IBOutlet UITextField *myTextField;
GTImageView *imageView;
int *sliderValue;
}
#property (nonatomic) int *sliderValue;
The header file of the view controller I am trying to send the data to
#import <UIKit/UIKit.h>
#interface GTImageView : UIViewController
{
UIScrollView* scrollView;
UIPageControl* pageControl;
int *someData;
}
#property (nonatomic) int *someData;
The implementation file where I want the variable someData to have the value I gave it in the first controller. NSLog is returning null in this implementation.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
UIImageView *animatedImageView =
[[UIImageView alloc] i nitWithFrame:CGRectMake(0, 55, 400, 550)];
[self.view addSubview:animatedImageView];
animatedImageView.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"IMG_0052.JPG"],
[UIImage imageNamed:#"IMG_0054.JPG"],
[UIImage imageNamed:#"IMG_0081.JPG"],
nil];
NSLog(#"some data = %#", someData);
// NSLog is returning null
int x = someData;
animatedImageView.animationDuration =
x * [animatedImageView.animationImages count];
[animatedImageView startAnimating];
[self.view addSubview: animatedImageView];
}
I believe you have yet to grasp the concept/idea for View Controller Life Cycle and also Model View Controller (MVC).
The GTImageView that you defined and initiated in changeButtonPressed for your First View Controller (GTSettingsVC) is a local object/instance for GTSettingsVC. If your view controller transition from GTSettingsVC to GTImageView, the data will not pass to there.
Since you are using UINavigationController, I believe you have Segue. The easiest way to pass data for UINavigationController is using prepareForSegue. You will have to prepare the data that you want to pass to the second view controller in this method before the transition to it.
You also make some mistake in GTImageView. someData is not an object, it should not have *. And also try not to use variable, use just the property in stead. It should be:-
#property (nonatomic) int someData;
In GTSettingsVC.M, add the following function:-
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
GTImageView * viewController = segue.destinationViewController;
viewController.someData = 99;
}
In GTImageView.H
#interface GTImageView : UIViewController
{
UIScrollView* scrollView;
UIPageControl* pageControl;
}
#property (nonatomic) int someData;
#end
In viewDidLoad in GTImageView.M
- (void)viewDidLoad
{
[super viewDidLoad];
UIImageView *animatedImageView =
[[UIImageView alloc] initWithFrame:CGRectMake(0,55, 400, 550)];
[self.view addSubview:animatedImageView];
animatedImageView.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"IMG_0052.JPG"],
[UIImage imageNamed:#"IMG_0054.JPG"],
[UIImage imageNamed:#"IMG_0081.JPG"],
nil];
NSLog(#"some data = %d", self.someData);
int x = self.someData;
animatedImageView.animationDuration =
x * [animatedImageView.animationImages count];
[animatedImageView startAnimating];
[self.view addSubview: animatedImageView];
}
I added a sample project to Github for your reference:-
https://github.com/voyage11/PassingDataTest
There is no need to take int *. Replace it by int and assign the value directly rather than address.
I did search first, and have seen somewhat similar issues, but no definitive answer on how to solve it. The problem I'm having with my app is that I have 3 navigation controllers that are added as child view controllers into a UIScrollView. I originally wanted to use a UIPageViewController instead, but that turned out to be a mess since you can't disable the bouncing on it. For each navigation controller, a tableView controller is embedded within it in storyboard.
viewDidAppear and viewDidDisappear are not called for my child view controllers because their views are added as subviews to the paging scroll view at runtime, and I kindof believe is why I can't figure out how to solve this.
I need each of my table view controller's to respond to the user touching the status bar for the respective tableView to scroll to the top.
Here is the code I'm using for the setup of the app's main scroll view and adding the 3 view controller's views to it:
I appreciate any help offered!
MainViewController.h
#import <UIKit/UIKit.h>
#interface MainViewController : UIViewController <UIScrollViewDelegate>
#end
MainViewController.m:
#import "MainViewController.h"
#interface MainViewController ()
#property (nonatomic, strong) UINavigationController *settings;
#property (nonatomic, strong) UINavigationController *hehTwo;
#property (nonatomic, strong) UINavigationController *hehOne;
#property (nonatomic, strong) IBOutlet UIScrollView *scrollView;
#end
#implementation MainViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.settings = [self.storyboard instantiateViewControllerWithIdentifier:#"Settings"];
self.hehTwo = [self.storyboard instantiateViewControllerWithIdentifier:#"HehTwo"];
self.hehOne = [self.storyboard instantiateViewControllerWithIdentifier:#"HehOne"];
[self addChildViewController:self.settings];
[self addChildViewController:self.hehTwo];
[self addChildViewController:self.hehOne];
CGRect hehTwoFrame = self.hehTwo.view.frame;
hehTwoFrame.origin.x = 320;
self.hehTwo.view.frame = hehTwoFrame;
CGRect hehOneFrame = self.hehOne.view.frame;
hehOneFrame.origin.x = 640;
self.hehOne.view.frame = hehOneFrame;
[self.scrollView addSubview:self.settings.view];
[self.scrollView addSubview:self.hehTwo.view];
[self.scrollView addSubview:self.hehOne.view];
// Setting offset so the farthest right controller is heh One
[self.scrollView setContentOffset:CGPointMake(640,0)];
self.scrollView.delegate = self;
self.scrollView.bounces = NO;
self.scrollView.delaysContentTouches = NO;
self.scrollView.contentSize = CGSizeMake(960, self.view.frame.size.height);
self.scrollView.scrollsToTop = NO;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
CGFloat width = scrollView.frame.size.width;
NSInteger page = (scrollView.contentOffset.x + (0.5f * width)) / width;
if (page == 0)
{
// Settings
}
else if (page == 1)
{
// Heh Two
}
else
{
// Heh One
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#end
First of all, you need to set self.tableView.scrollsToTop = NO; on HehTwo and HehOne (if these two are initially hidden) in their viewDidLoad implementation.
And now, update this method:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
CGFloat width = scrollView.frame.size.width;
NSInteger page = (scrollView.contentOffset.x + (0.5f * width)) / width;
if (page == 0)
{
// Settings
((UITableViewController *)self.settings.viewControllers[0]).tableView.scrollsToTop = YES;
((UITableViewController *)self.hehOne.viewControllers[0]).tableView.scrollsToTop = NO;
((UITableViewController *)self.hehTwo.viewControllers[0]).tableView.scrollsToTop = NO;
}
else if (page == 1)
{
// Heh Two
((UITableViewController *)self.settings.viewControllers[0]).tableView.scrollsToTop = NO;
((UITableViewController *)self.hehOne.viewControllers[0]).tableView.scrollsToTop = NO;
((UITableViewController *)self.hehTwo.viewControllers[0]).tableView.scrollsToTop = YES;
}
else
{
// Heh One
((UITableViewController *)self.settings.viewControllers[0]).tableView.scrollsToTop = NO;
((UITableViewController *)self.hehOne.viewControllers[0]).tableView.scrollsToTop = YES;
((UITableViewController *)self.hehTwo.viewControllers[0]).tableView.scrollsToTop = NO;
}
}
That's all! This should fix it.
I am writing a simple application that consists of 2 UIImageViews and 2 UIButtons. The UIImageViews are placed on top of the UIButtons.
I have 1 UIImage that appears on a random UIImageView and disappears after 2 seconds. The user then has to tap on the button they think the image appeared on.
I shuffle the UIImageView array and use the first element (index 0) for the image to be displayed on. When shuffling I keep track of which element (i.e from which index. lets say from index "n") was placed on index 0 of the array.
However, when a button is pressed i compare the id of the button pressed with the id of the button with index n. (because that is the index of the random UIImageView).
But for some reason it is not working. :(
Here is my code: (i didn't upload the .h file. it just contains declarations.)
The code below doesn't produce any error/warning messages. It just doesn't output the result I want.
#interface ViewController ()
#property (strong, nonatomic) NSMutableArray* tempButton;
#property (strong, nonatomic) NSMutableArray *tempViews;
#property (strong, nonatomic) UIImage *myImage;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
_myImage = [UIImage imageNamed:#"hello"];
_tempButton = [[NSMutableArray alloc] initWithObjects:_button1, _button2, nil];
_tempViews = [[NSMutableArray alloc]initWithObjects:_image1, _image2, nil];
[self displayonView];
}
-(void)displayToFindSymbol{
[_toFindImage setImage:_myImage];
_toFindImage.contentMode = UIViewContentModeScaleAspectFit;
}
- (IBAction)pressed:(id)sender {
UIButton *result = (UIButton *)sender;
if (result == _tempButton[_correctButton]) {
NSLog (#"Correct");
}
else if (result != _tempButton[_correctButton]){
NSLog (#"Incorrect");
}
}
-(NSMutableArray *)shuffleViews{
NSUInteger count = _tempViews.count;
int n;
for (int i=count-1; i>=0; --i) {
n = arc4random() % (i + 1);
[_tempViews exchangeObjectAtIndex:n withObjectAtIndex:i];
}
_correctButton = n;
return _tempViews;
}
-(void)displayonView{
NSMutableArray *tempArray;
tempArray = [self shuffleViews]; // shuffle views
_correctImage = [tempArray objectAtIndex:0];
_correctImage.contentMode = UIViewContentModeScaleAspectFit;
[_correctImage setImage:_myImage];
NSTimer* myTImer;
myTImer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(hideLabel) userInfo:nil repeats:NO];
}
-(void) hideLabel{
_correctImage.hidden = YES;
for (UIButton *each in self.tempButton) {
each.enabled = YES;
}
[self displayToFindSymbol];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
Use tags instead, set a unique tag to both of the buttons, and set the tag of image to the button that the image will belong, later on, compare the tag of both image and the button to check if they are the same or not.
https://developer.apple.com/library/ios/documentation/uikit/reference/uiview_class/UIView/UIView.html#//apple_ref/occ/instp/UIView/tag
I'm kinda new to objective-c and iOS aswell, but i don't think you should compare like this:
result == _tempButton[_correctButton]
try this comparison instead:
[result isEqual:_tempButton[_correctButton]]
I have some images I'm trying to load within a scroll view similar to apple's page control example. My app crashes with an error of
'NSInvalidArgumentException', reason: '-[TutorialViewController
loadScrollViewWithPage:]: unrecognized selector sent to instance
0x687d0b0'
I think I understand enough of this that it's telling me that I don't have a method for the selector... but I'm not sure how to fix it! Thank you in advance.
Header File
//TutorialViewController.h
#import
#interface TutorialViewController : UIViewController <UIScrollViewDelegate>
{
// To be used when scrolls originate from the UIPageControl
BOOL pageControlUsed;
int pageNumber;
}
#property (nonatomic, retain) NSArray *iPhoneTutorial;
#property (nonatomic, retain) IBOutlet UIScrollView *scrollView;
#property (nonatomic, retain) IBOutlet UIPageControl *pageControl;
#property (nonatomic, retain) NSMutableArray *viewControllers;
- (IBAction)changePage:(id)sender;
#end
Implementation File
//TutorialViewController.m
#import "TutorialViewController.h"
static NSUInteger kNumberOfPages = 3;
static NSString *NameKey = #"nameKey";
static NSString *ImageKey = #"imageKey";
#interface TutorialViewController (PrivateMethods)
- (void)loadScrollViewWithPage:(int)page;
- (void)scrollViewDidScroll:(UIScrollView *)sender;
#end
#implementation TutorialViewController
#synthesize scrollView, pageControl;
- (void)awakeFromNib
{
// load our data from a plist file inside our app bundle
NSString *path = [[NSBundle mainBundle] pathForResource:#"iPhoneTutorial" ofType:#"plist"];
self.iPhoneTutorial = [NSArray arrayWithContentsOfFile:path];
// view controllers are created lazily
// in the meantime, load the array with placeholders which will be replaced on demand
NSMutableArray *controllers = [[NSMutableArray alloc] init];
for (unsigned i = 0; i < kNumberOfPages; i++)
{
[controllers addObject:[NSNull null]];
}
//self.viewControllers = controllers;
//[controllers release];
// a page is the width of the scroll view
scrollView.pagingEnabled = YES;
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * kNumberOfPages, scrollView.frame.size.height);
scrollView.showsHorizontalScrollIndicator = NO;
scrollView.showsVerticalScrollIndicator = NO;
scrollView.scrollsToTop = NO;
scrollView.delegate = self;
pageControl.numberOfPages = kNumberOfPages;
pageControl.currentPage = 0;
// pages are created on demand
// load the visible page
// load the page on either side to avoid flashes when the user starts scrolling
//
[self loadScrollViewWithPage:0];
[self loadScrollViewWithPage:1];
}
// load the view nib and initialize the pageNumber ivar
- (id)initWithPageNumber:(int)page
{
pageNumber = page;
return self;
}
- (void)scrollViewDidScroll:(UIScrollView *)sender
{
// We don't want a "feedback loop" between the UIPageControl and the scroll delegate in
// which a scroll event generated from the user hitting the page control triggers updates from
// the delegate method. We use a boolean to disable the delegate logic when the page control is used.
if (pageControlUsed)
{
// do nothing - the scroll was initiated from the page control, not the user dragging
return;
}
// Switch the indicator when more than 50% of the previous/next page is visible
CGFloat pageWidth = scrollView.frame.size.width;
int page = floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
pageControl.currentPage = page;
// load the visible page and the page on either side of it (to avoid flashes when the user starts scrolling)
[self loadScrollViewWithPage:page - 1];
[self loadScrollViewWithPage:page];
[self loadScrollViewWithPage:page + 1];
// A possible optimization would be to unload the views+controllers which are no longer visible
}
// At the begin of scroll dragging, reset the boolean used when scrolls originate from the UIPageControl
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
pageControlUsed = NO;
}
// At the end of scroll animation, reset the boolean used when scrolls originate from the UIPageControl
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
pageControlUsed = NO;
}
- (IBAction)changePage:(id)sender
{
int page = pageControl.currentPage;
// load the visible page and the page on either side of it (to avoid flashes when the user starts scrolling)
[self loadScrollViewWithPage:page - 1];
[self loadScrollViewWithPage:page];
[self loadScrollViewWithPage:page + 1];
// update the scroll view to the appropriate page
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
[scrollView scrollRectToVisible:frame animated:YES];
// Set the boolean used when scrolls originate from the UIPageControl. See scrollViewDidScroll: above.
pageControlUsed = YES;
}
- (void)viewDidLoad
{
// Do any additional setup after loading the view, typically from a nib.
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
You have to add an
- (void)loadScrollViewWithPage:(int)page
method where you add your view
like
switch(page) {
case 0:
myView1 = [[MyView1ViewController alloc] initWithNibName:#"MyView1ViewController" bundle:nil];
[scrollView addSubview: myViewPage1.view];
break;
}
But the Apple Demo "PageControl" has such a method in File PhoneContentViewController.m
I need to generate a grid of buttons for an iOS app. Each button needs two parameters: the number of the column and the number of the row. A button will also have two states, activated and deactivated.
When the app is loaded I want there to be like 21 rows and 16 columns. And somewhere on the screen there will also be a button that says "add columns" and this would add 4 extra columns every time it's clicked.
Any suggestions how I should do this? I could start by adding the first 21*16 buttons with the IB but will that allow me to extend it with extra columns later on, and how?
Edit: the bounty was only started to reward mbm30075, no new answers necessary
I believe this is a more complete solution. Here's the .h/.m pair I wrote up for testing:
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (assign, nonatomic) int numColumns;
#property (assign, nonatomic) int numRows;
#property (strong, nonatomic) NSMutableArray *buttonsArray;
#property (strong, nonatomic) IBOutlet UIScrollView *scrollView;
#property (strong, nonatomic) IBOutlet UIButton *addButtons;
#property (strong, nonatomic) IBOutlet UIView *buttonsView;
- (IBAction)addFourMoreColumns;
#end
ViewController.m
#import "ViewController.h"
#implementation ViewController
#synthesize addButtons;
#synthesize buttonsArray;
#synthesize buttonsView;
#synthesize numColumns;
#synthesize numRows;
#synthesize scrollView;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self setButtonsArray:[NSMutableArray array]];
[self setNumColumns:16];
[self setNumRows:21];
[self layoutButtons];
}
- (void)layoutButtons {
static int width = 100;
static int height = 37;
static int buffer = 8; // space between buttons (horiz. & vert.)
static int margin = 20;
CGPoint topLeft = CGPointMake(margin,margin); // standard "top left" in iOS
// Since you appear to be wanting to modify the number of columns,
// I'm going to make the multi-dimension array an array of columns,
// with each column containing an array of buttons (representing the rows)
// Iterate through how many columns SHOULD exist ([self numColumns])
for (int i = 0; i < [self numColumns]; i = i + 1) {
// Check if this "column" exists (does this index exist in [self buttonsArray]?)
if (i >= [[self buttonsArray] count]) {
// It doesn't exist, so we need to add a blank array
[[self buttonsArray] addObject:[NSMutableArray array]];
}
NSMutableArray *column = [[self buttonsArray] objectAtIndex:i];
// Now, we iterate through how many rows/buttons SHOULD exist ([self numRows])
for (int j = 0; j < [self numRows]; j = j + 1) {
// Check if this "row"/"cell"/"button" exists
if (j >= [column count]) {
// It doesn't exist, so we need to add a new button AND PLACE IT!
// Of course, you need to make your button type correctly
// This is just standard button code...
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btn setFrame:CGRectMake(topLeft.x,topLeft.y,width,height)];
// Do whatever else you need to do with the button...
// Set title...
[btn setTitle:[NSString stringWithFormat:#"(%d,%d)", i + 1, j + 1] forState:UIControlStateNormal];
// Add target actions...
[btn addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
// Add the button to the view
[[self buttonsView] addSubview:btn];
// Add the button to the array
[column addObject:btn];
}
// Increment topLeft to the next "row" for correct button placement...
topLeft = CGPointMake(topLeft.x, topLeft.y + height + buffer);
}
// Increment topLeft to the next "column" for correct button placement...
topLeft = CGPointMake(topLeft.x + width + buffer, margin);
}
// So, I'm assuming your "add columns" button will be placed equivalent to
// "(columnCount + 1, 1)", or at the top of the screen, just to the right
// of the right-most column of buttons
// [self addButtons] is the property to the UIButton that calls [self addFourMoreColumns]
[[self addButtons] setFrame:CGRectMake(topLeft.x, topLeft.y, [[self addButtons] frame].size.width, [[self addButtons] frame].size.height)];
// Now, update the view that holds the buttons to give it a new size (based on the buttons added)
CGRect viewFrame = CGRectMake(0, 0, CGRectGetMaxX([[self addButtons] frame]) + buffer, 20 + ([[self buttonsArray] count] * (height + buffer)));
[[self buttonsView] setFrame:viewFrame];
[[self scrollView] setContentSize:viewFrame.size];
// Redraw the view...
[[self view] setNeedsDisplay];
}
- (IBAction)addFourMoreColumns {
[self setNumColumns:[self numColumns] + 4];
[self layoutButtons];
}
// Shows in the log which button you pressed: "(col, row)"
- (void)buttonPressed:(id)sender {
for (int i = 0; i < [[self buttonsArray] count]; i = i + 1) {
NSMutableArray *col = [[self buttonsArray] objectAtIndex:i];
for (int j = 0; j < [col count]; j = j + 1) {
if (sender == [col objectAtIndex:j]) {
NSLog(#"button (%d,%d) pressed", i + 1, j + 1);
break;
}
}
}
}
#end
Xib setup is basic with:
View // tied to [ViewController view]
|
--->ScrollView // tied to [ViewController scrollView]
|
--->View // tied to [ViewController buttonsView]
|
--->UIButton // tied to [ViewController addButtons]
this can be achieved using the scroll view UIScrollView and using two for loops to add required buttons at run time like
for(int col = 0; col < [max column]; col++)
{
for(int row = 0; row < [max row]; row++)
{
//add buttons assigning them proper frame size
}
}
You will need to add buttons programmatically using 2 loops. Also to identify the buttons assign them tags which are a number made by combination of column number and row number.
Eg:- button at row 1 and column 1 may have tag as 11.
Using the tag values you can identify which button is clicked and perform corresponding action.