How to display images on button action - ios

I have 10 UIImages. When I click the UIButton it displaying under UIScrollView. But I need to implement theUIButtonlike **Next**, ifUIButtonis clicked first time, it displays the firstUIImage`, then after that, on click it displays next image. If I click the back button, the previous image should be displayed.
int currentIndex = 0;
int MAX_COUNT;
NSMutableArray *imageName = [[NSMutableArray alloc] initWithObjects:
#"spices.jpg",
#"spice_powder.jpg",
#"turmeric.jpg",
#"whynani_img3.jpg",
#"spice_blends.jpg",
#"products1.png", nil];
currentIndex = currentIndex + 1;
if(currentIndex > MAX_COUNT) {
currentIndex = MAX_COUNT;
}
for (int i = 0; i<[imageName count]; i++ ) {
UIImageView *mmageView =
[[UIImageView alloc] initWithFrame:CGRectMake(200,200,350,350)];
[mmageView setImage:[UIImage imageNamed:[imageName objectAtIndex:i]]];
[self.view addSubview:mmageView];
}

Declare a global imageView and an int in interface file
UIImageView *imgView;
int index;
In viewDidLoad:
index = 0;
imgView = [[UIImageView alloc] initWithFrame:CGRectMake(200,200,350,350)];
[imgView setImage:[UIImage imageNamed:[imageName objectAtIndex:index]]];
[self.view addSubView:imgView];
In Next Button Action
-(void)nextButtonAction
{
++index;
[previousBtn setEnabled:YES];
if (index > [imageName count])
{
index = [imageName count] - 1;
[nextBtn setEnabled:NO];
}
[imgView setImage:[UIImage imageNamed:[imageName objectAtIndex:index]]];
}
In Previous Button Action
-(void)previousButtonAction
{
--index;
[nextBtn setEnabled:YES];
if (index < 0)
{
index = 0;
[previousBtn setEnabled:NO];
}
[imgView setImage:[UIImage imageNamed:[imageName objectAtIndex:index]]];
}

You can do the same using a UIViewController having 2 UIButtons with custom images depicting forward and back along with UIImageView. On selecting the next / back button load the appropriate image. The image name has to be stored in an NSArray.
Hope this helps.
Edit: sample code as given below,
In .h file
#property(nonatomic, weak) UIImageView *imageView;
#property(nonatomic, weak) UIButton *nextButton;
#property(nonatomic, weak) UIButton *backButton;
(IBAction)btnNextBtn:(id)sender;
(IBAction)btnBackBtn:(id)sender;
In .m file
(void)viewDidLoad {
currentIndex = 0;
NSMutableArray *imageName = [[NSMutableArray alloc] initWithObjects:#"Myprofile.png",
#"great_ideas_wordle2.png", #"Review.png",
#"collaborate.png", nil];
imageView = [[UIImageView alloc] initWithFrame:CGRectMake(200,200,350,350)];
[imageView setImage:[UIImage imageNamed:[imageName objectAtIndex:currentIndex]]];
[self.view addSubView:imageView];
}
(IBAction)btnNextBtn:(id)sender {
currentIndex = currentIndex + 1;
if(currentIndex > MAX_COUNT) {
currentIndex = MAX_COUNT;
}
// load the image view with the currentIndex from the array.
[imageView setImage:[UIImage imageNamed:[imageName objectAtIndex:currentIndex]]];
}
(IBAction)btnBackBtn:(id)sender {
currentIndex = currentIndex - 1;
if (currentIndex < 0) {
currentIndex = 0;
}
// load the image view with the currentIndex from the array.
[imageView setImage:[UIImage imageNamed:[imageName objectAtIndex:currentIndex]]];
}

write this in .h file
#property (nonatomic,retain)IBOutlet UIImageView *imageview1;
#property (nonatomic,retain)IBOutlet UIButton *pre,*next;
#property (nonatomic,retain) NSArray *images;
#property (nonatomic) int currentindex;
-(IBAction)prebtn:(id)sender;
-(IBAction)nextbtn:(id)sender;
write this code in .m file
#implementation ViewController
#synthesize images;
#synthesize currentindex;
#synthesize pre,next;
#synthesize imageview1;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.currentindex = 0;
self.images = [[NSArray alloc] initWithObjects:#"images-2.jpeg",#"images- 3.jpeg",#"images.jpeg", nil];
imageview1.image = [UIImage imageNamed:#"images-2.jpeg"];
[pre setEnabled:NO];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(IBAction)nextbtn:(id)sender{
currentindex = currentindex + 1;
[pre setEnabled:YES];
if (currentindex >= [images count])
{
currentindex = currentindex - 1;
[next setEnabled:NO];
}
imageview1.image = [UIImage imageNamed:[images objectAtIndex:currentindex]];
}
-(IBAction)prebtn:(id)sender{
currentindex = currentindex - 1;
[next setEnabled:YES];
if(currentindex < 0)
{
currentindex = 0;
[pre setEnabled:NO];
}
imageview1.image = [UIImage imageNamed:[images objectAtIndex:currentindex]];
}
#end

Try with this code
.h file
#property(nonatomic, strong) UIImageView *imageView;
#property(nonatomic, strong) UIButton *nextButton;
#property(nonatomic, strong) UIButton *previousButton;
#property(nonatomic, strong) NSMutableArray *imagesArrayName;
#property(nonatomic) int currentIndex;
-(IBAction)btnNextImage:(id)sender;
-(IBAction)btnPreviousImage:(id)sender;
.m file
- (void)viewDidLoad {
[super viewDidLoad];
self.currentIndex = 0;
NSMutableArray *imagesArrayName = [[NSMutableArray alloc] initWithObjects:
#"spices.jpg",
#"spice_powder.jpg",
#"turmeric.jpg",
#"whynani_img3.jpg",
#"spice_blends.jpg",
#"products1.png", nil];
[self.nextButton addTarget:self action:#selector(btnNextImage:) forControlEvents:UIControlEventTouchUpInside];
[self.previousButton addTarget:self action:#selector(btnPreviousImage:) forControlEvents:UIControlEventTouchUpInside];
[self.imageView setImage[UIImage imageNamed:(NSString*)[imagesArrayName objectAtIndex:currenIndex]]];
[self.previousButton setEnabled:FALSE];
}
-(IBAction)btnNextImage:(id)sender {
self.currentIndex = self.currentIndex + 1;
[self.imageView setImage[UIImage imageNamed:(NSString*)[imagesArrayName objectAtIndex:currenIndex]]];
if (self.currentIndex == [self.imagesArrayName count] - 1) {
[self.nextButton setEnabled:FALSE];
}
[self.previousButton setEnabled:TRUE];
}
-(IBAction)btnPreviousImage:(id)sender{
self.currentIndex = self.currentIndex - 1;
[self.imageView setImage[UIImage imageNamed:(NSString*)[imagesArrayName objectAtIndex:currenIndex]]];
if (self.currentIndex == 0) {
[self.previousButton setEnabled:FALSE];
}
[self.nextButton setEnabled:TRUE];
}

Related

Finding 5 in a row

Background:
Im building a game "kinda" like connect 4.
I have most of it working, the only part I'm stuck at now is determining if there are 5 of the same colors in a row (left,right,up,down & diagonal)
Question:
How can I get the code to loop and see if there are 5 pieces in a row with the same color in any direction.
Note - Each turn is played by moving one piece on the board to a new position and than 3 new pieces come into play.
That means that it would have to check for a match of 5 after the turn and also after the 3 new pieces get randomly placed onto the board.
Thank you!
My code for the game so far is..
ViewController(.m)
#import "ViewController.h"
#import "BoardCell.h"
#import <QuartzCore/QuartzCore.h>
#interface ViewController ()
#property (strong,nonatomic) NSArray *imageNames;
#property (strong,nonatomic) NSMutableArray *board;
#property NSInteger lastMove;
#define BOARDWIDTH 9
#define BOARDHEIGHT 9
#end
static int moves[]={-BOARDWIDTH,-1,1,BOARDWIDTH};
bool preSelect;
BoardCell *startCell;
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
preSelect = NO;
self.imageNames = #[#"marble_red",#"marble_blue",#"marble_purple",#"marble_orange",#"marble_green"];
self.board = [NSMutableArray new];
for (int y=0; y < BOARDWIDTH; y++) {
for (int x = 0; x < BOARDHEIGHT; x++) {
UIButton * button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(5+ 35 * x, 100 + 35 * y, 30, 30);
button.tag = y*BOARDWIDTH+x;
//[button setTitle:[NSString stringWithFormat:#"%ld", button.tag] forState:UIControlStateNormal];
button.selected = NO;
[button.layer setCornerRadius:15];
[button setBackgroundColor:[UIColor colorWithWhite:.7 alpha:.5]];
[button addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview: button];
[self.board addObject:[[BoardCell alloc] initWithButton:button]];
}
}
self.lastMove=arc4random_uniform(BOARDWIDTH*BOARDHEIGHT);
UIButton *button=(UIButton *)[self.view viewWithTag:self.lastMove];
[button setBackgroundImage:[UIImage imageNamed:#"greensquare"] forState:UIControlStateNormal];
[self addRandoms:3];
}
-(void) addRandoms:(NSInteger)randomCount {
for (int i = 0; i < randomCount; i++) {
int space = arc4random_uniform(BOARDWIDTH*BOARDHEIGHT);
BoardCell *cell=self.board[space];
if (!cell.occupied) {
int pic = arc4random_uniform((u_int32_t)self.imageNames.count);
NSString *string = [self.imageNames objectAtIndex:pic];
NSString *highlighted = [NSString stringWithFormat:#"%#_highlighted",string];
NSLog(#"HIGHLIGHTED = %#",highlighted);
[cell.button setBackgroundImage:[UIImage imageNamed:string] forState:UIControlStateNormal];
[cell.button setTitleColor:[UIColor lightGrayColor] forState:UIControlStateNormal];
[cell.button setTitleColor:[UIColor blackColor] forState:UIControlStateSelected];
cell.button.selected = NO;
cell.occupied=YES;
}
else {
i--;
}
}
}
-(void)buttonPressed:(UIButton *)button
{
NSInteger buttonId=button.tag;
BoardCell *cell=self.board[buttonId];
if (!preSelect) {
if (cell.occupied) {
//cell.button.selected = YES;
[[cell.button layer] setBorderWidth:3.5f];
[cell.button.layer setBorderColor:[[UIColor colorWithWhite:.85 alpha:.7]CGColor]];
cell.button.highlighted = YES;
preSelect = YES;
self.lastMove = buttonId;
startCell = cell;
}else{
cell.button.selected = NO;
cell.button.highlighted = NO;
[cell.button.layer setBorderColor:[[UIColor clearColor]CGColor]];
}
}else{
NSLog(#"SECOND STEP");
if (!cell.occupied) {
BoardCell *startCell=self.board[self.lastMove];
startCell.occupied=NO;
if ([self validMoveFromSquare:self.lastMove toDestination:buttonId]) {
[cell.button setBackgroundImage:[startCell.button backgroundImageForState:UIControlStateNormal]
forState:UIControlStateNormal];
[startCell.button setBackgroundImage:[UIImage imageNamed:#""] forState:UIControlStateNormal];
NSLog(#"FROM %ld, TO %ld",(long)self.lastMove,(long)buttonId);
cell.button.selected = NO;
cell.button.highlighted = NO;
startCell.button.selected = NO;
startCell.button.highlighted = NO;
self.lastMove=buttonId;
cell.occupied=YES;
preSelect = NO;
[self addRandoms:3];
}else{
startCell.occupied=YES;
preSelect = NO;
cell.button.selected = NO;
cell.button.highlighted = NO;
startCell.button.selected = NO;
startCell.button.highlighted = NO;
NSLog(#" INVALID FROM %ld, TO %ld",(long)self.lastMove,(long)buttonId);
}
}
preSelect = NO;
cell.button.selected = NO;
cell.button.highlighted = NO;
startCell.button.selected = NO;
startCell.button.highlighted = NO;
[cell.button.layer setBorderColor:[[UIColor clearColor]CGColor]];
[startCell.button.layer setBorderColor:[[UIColor clearColor]CGColor]];
}
}
-(BOOL) validMoveFromSquare:(NSInteger)startSquare toDestination:(NSInteger)destination {
for (int limit=1;limit<10;limit++ ) {
NSMutableIndexSet *visitList=[NSMutableIndexSet new];
if ([self DFSFromStart:startSquare toGoal:destination withLimit:limit andVisitList:visitList]) {
return YES;
}
}
return NO;
}
-(BOOL) DFSFromStart:(NSInteger)start toGoal:(NSInteger)goal withLimit:(NSInteger)limit andVisitList:(NSMutableIndexSet *)visitList {
if (limit >=0) {
if (((BoardCell *)self.board[start]).occupied) {
NSLog(#"Self Board = %#",self.board[start]);
return NO;
}
[visitList addIndex:start];
for (int i=0;i<4;i++) {
NSInteger nextPosition=start+moves[i];
NSLog(#"Next spot = %ld",(long)nextPosition);
if (nextPosition == goal) {
return YES;
}
if (nextPosition >=0 && nextPosition < BOARDWIDTH*BOARDHEIGHT) {
if (![visitList containsIndex:nextPosition]) {
if ([self DFSFromStart:nextPosition toGoal:goal withLimit:limit-1 andVisitList:visitList]) {
return YES;
}
}
}
}
}
return NO;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
BoardCell.m
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#interface BoardCell : NSObject
#property (weak,nonatomic,readonly) UIButton *button;
#property BOOL occupied;
-(id) initWithButton:(UIButton *)button;
#end
Thank you again!
You can use a recursive algorithm to work in each of the eight directions until you hit a boundary or a different color -
-(void) clearRunsOfColor:(Colors)color fromPoint:(NSInteger)startPoint {
NSInteger left=[self runFromStart:startPoint-1 ofColor:color inDirection:-1];
NSInteger right=[self runFromStart:startPoint+1 ofColor:color inDirection:1];
BOOL cleared=NO;
if (left+right+1 >4) {
[self clearBoardFromStart:startPoint-1 inDirection:-1 forLength:left];
[self clearBoardFromStart:startPoint+1 inDirection:1 forLength:right];
cleared=YES;
}
NSInteger up=[self runFromStart:startPoint-BOARDWIDTH ofColor:color inDirection:-BOARDWIDTH];
NSInteger down=[self runFromStart:startPoint+BOARDWIDTH ofColor:color inDirection:BOARDWIDTH];
if (up+down+1 > 4) {
[self clearBoardFromStart:startPoint-BOARDWIDTH inDirection:-BOARDWIDTH forLength:up];
[self clearBoardFromStart:startPoint+BOARDWIDTH inDirection:BOARDWIDTH forLength:down];
cleared=YES;
}
NSInteger NW=[self runFromStart:startPoint-BOARDWIDTH-1 ofColor:color inDirection:-BOARDWIDTH-1];
NSInteger SE=[self runFromStart:startPoint+BOARDWIDTH+1 ofColor:color inDirection:+BOARDWIDTH+1];
if (NW+SE+1 > 4) {
[self clearBoardFromStart:startPoint-BOARDWIDTH-1 inDirection:-BOARDWIDTH-1 forLength:NW];
[self clearBoardFromStart:startPoint+BOARDWIDTH+1 inDirection:BOARDWIDTH+1 forLength:SE];
cleared=YES;
}
NSInteger NE=[self runFromStart:startPoint-BOARDWIDTH+1 ofColor:color inDirection:-BOARDWIDTH+1];
NSInteger SW=[self runFromStart:startPoint+BOARDWIDTH-1 ofColor:color inDirection:+BOARDWIDTH-1];
if (NE+SW+1 > 4) {
[self clearBoardFromStart:startPoint-BOARDWIDTH+1 inDirection:-BOARDWIDTH+1 forLength:NE];
[self clearBoardFromStart:startPoint+BOARDWIDTH-1 inDirection:BOARDWIDTH-1 forLength:SW];
cleared=YES;
}
if (cleared) {
[self occupyCell:startPoint withPiece:nil];
}
}
-(void) clearBoardFromStart:(NSInteger)start inDirection:(NSInteger)direction forLength:(NSInteger) length {
NSInteger pos=start;
for (int i=0;i<length;i++) {
[self occupyCell:pos withPiece:nil];
pos+=direction;
}
}
-(NSInteger) runFromStart:(NSInteger)start ofColor:(Colors)color inDirection:(NSInteger)direction {
if ([self inBounds:start]) {
BoardCell *thisCell=self.board[start];
if (thisCell.gamepiece != nil && thisCell.gamepiece.color == color) {
if ([self validDestination:start+direction withMove:(int)direction fromSquare:start]) {
return ([self runFromStart:start+direction ofColor:color inDirection:direction]+1);
}
else {
return 1;
}
}
}
return 0;
}
-(BOOL) inBounds:(NSInteger) position {
if (position >=0 && position < BOARDHEIGHT*BOARDWIDTH) {
return YES;
}
else {
return NO;
}
}
None of the code below is tested for correctness.
You could update your BoardCell class like so:
typedef enum {
TopLeft, Top, TopRight,
Left, Right,
BottomLeft, Bottom, BottomRight,
NumberOfDirections
} BoardCellAdjacentDirection;
#interface BoardCell
- (void)addAdjacentCell:(BoardCell *)cell forDirection:(BoardCellAdjacentDirection)direction;
- (NSInteger)occupiedCellsInDirection:(BoardCellAdjacentDirection)direction;
#end
#implementation BoardCell {
NSMutableArray *adjacentCells;
}
- (instancetype)init {
if (self = [super init]) {
adjacentCells = [[NSMutableArray alloc] init];
for (NSInteger i = 0; i < (NSInteger)NumberOfDirections; i++) {
[adjacentCells addObject:[NSNull null]];
}
}
return self;
}
- (void)addAdjacentCell:(BoardCell *)cell forDirection:(BoardCellAdjacentDirection)direction {
[adjacentCells setObject:cell atIndex:(NSInteger)direction];
}
- (NSInteger)occupiedCellsInDirection:(BoardCellAdjacentDirection)direction {
if (!self.occupied) return 0;
if (adjacentCells[direction] == [NSNull null]) return 1;
return [adjacentCells[direction] occupiedCellsInDirection:direction]+1;
}
#end
Wherever you create your BoardCell objects, you'll need to add the appropriate adjacent cells. You'll also probably want to put in some sanity checks to make sure that cell adjacency is a two-way relationship (i.e. cell A is left-adjacent to B and B is right-adjacent to A).
Edit You'll probably also want to add a method to determine if you've injected a cell into the centre of a line.
typedef enum {
BackSlash,
ForwardSlash,
Vertical,
Horizontal
} BoardCellAxis;
...
- (NSInteger)occupiedCellsOnAxis:(BoardCellAxis)axis {
switch (axis) {
case BackSlash:
return MAX(0, [self occupiedCellsInDirection:TopLeft]
+ [self occupiedCellsInDirection:BottomRight]
- 1); // Don't count yourself twice.
case ForwardSlash:
return MAX(0, [self occupiedCellsInDirection:TopRight]
+ [self occupiedCellsInDirection:BottomLeft]
- 1); // Don't count yourself twice.
case Vertical:
return MAX(0, [self occupiedCellsInDirection:Top]
+ [self occupiedCellsInDirection:Bottom]
- 1); // Don't count yourself twice.
case Horizontal:
return MAX(0, [self occupiedCellsInDirection:Left]
+ [self occupiedCellsInDirection:Right]
- 1); // Don't count yourself twice.
}
}

How to implement a UIPageControl properly?

I have 3 minor issues related to implementing a UIPageControl. I'm not using a UIPageViewController, so I would not like to use that, if possible.
I have implemented a UIPageControl, where, when a user swipes either left or right on the view, it will move to the next "page" and display a different image.
Here is the following code:
ViewController.h:
#property (nonatomic) NSInteger Count;
#property (strong, nonatomic) IBOutlet UIPageControl *Control;
#property (strong, nonatomic) IBOutlet UIImageView *imageView;
#property (strong, nonatomic) IBOutlet UILabel *label;
#property (strong, nonatomic) UISwipeGestureRecognizer *swipeRight, *swipeLeft;
#property (strong, nonatomic) NSArray *array;
ViewController.m:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.array = #[#"page1", #"page2", #"page3", #"page4"];
self.swipeRight = [ [UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(Right:)];
self.swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
[self.view addGestureRecognizer:self.swipeRight];
self.swipeLeft = [ [UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(Left:)];
self.swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
[self.view addGestureRecognizer:self.swipeLeft];
self.Control.numberOfPages = 3;
self.Control.currentPage = 0;
}
-(void)Right: (UITapGestureRecognizer *)sender
{
self.Count = self.Count - 1;
if (self.Count > 3)
{
self.Count = 1;
}
else if (self.Count < 1)
{
self.Count = 3;
}
if (self.Count == 1)
{
self.Control.currentPage = 0;
self.imageView.image = [UIImage imageNamed:[self.array objectAtIndex:self.Control.currentPage]];
// self.label.text = #"this is page 1";
}
else if (self.Count == 2)
{
self.Control.currentPage = 1;
self.imageView.image = [UIImage imageNamed:[self.array objectAtIndex:self.Control.currentPage]];
// self.label.text = #"this is page 2";
}
else if (self.Count == 3)
{
self.Control.currentPage = 2;
self.imageView.image = [UIImage imageNamed:[self.array objectAtIndex:self.Control.currentPage]];
// self.label.text = #"this is page 3";
}
}
-(void)Left: (UITapGestureRecognizer *)sender
{
self.Count = self.Count + 1;
if (self.Count > 3)
{
self.Count = 1;
}
else if (self.Count < 1)
{
self.Count = 3;
}
if (self.Count == 1)
{
self.Control.currentPage = 0;
self.imageView.image = [UIImage imageNamed:[self.array objectAtIndex:self.Control.currentPage]];
//self.label.text = #"this is page 1";
}
else if (self.Count == 2)
{
self.Control.currentPage = 1;
self.imageView.image = [UIImage imageNamed:[self.array objectAtIndex:self.Control.currentPage]];
//self.label.text = #"this is page 2";
}
else if (self.Count == 3)
{
self.Control.currentPage = 2;
self.imageView.image = [UIImage imageNamed:[self.array objectAtIndex:self.Control.currentPage]];
// self.label.text = #"this is page 3";
}
}
The first issue: how do I make the view display the first image at index 0 on launch?
Right now, if you start the app initially, the image is blank on screen even though the page control shows the current view as being highlighted with the little dot. You have to swipe left to get the first image in index 0 to display.
The second issue: how do I add a scroll transition style animation when swiped left or right?
Right now, if you swipe either left or right, the image transition is instant, and you don't see that swiping animation where one image pushes the other image out of the view.
The third issue: how do I make the swipe gesture recognition not be the whole view area, but only be swipeable if you swipe on the upper portion of the view?
Feel free to download the project code as it's just a template that I'm using:
project code
Thanks

Xcode - IB elements not shown in my view at runtime

I've got a very weird problem with my iOS project.
I have a UIViewController with some labels and buttons and when user enters this view I programmatically build a gameboard (it's the minesweeper game).
What I wanted to do now is add a simple element (in my case a segmented control but i tried also with a button and doesn't work) at the bottom or at the beginning of the board.
When I add something from the Interface Builder I can see that in the storyboard but when I run the app puff, it's disappeared!
View contains only the "old" elements and the new one is not shown.
Yes I made a IBOutlet:
#property (weak, nonatomic) IBOutlet UISegmentedControl *clickTypeSegmentedControl;
And yes I checked if references of segemented control are ok.
I can't really understand what is wrong, if someone can help I'll be very grateful.
** EDIT: I added code of the ViewController, there are some other methods I left out because they only handle the game. I repeat: even if I add a simple button with no actions, it will not be shown.
#import "GameViewController.h"
#import "GameBoardModel.h"
#import "ScoreViewController.h"
#import <AVFoundation/AVFoundation.h>
#define UIColorFromRGB(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]
#interface GameViewController ()
#property (weak, nonatomic) IBOutlet UILabel *timerLabel;
#property (weak, nonatomic) IBOutlet UILabel *bombsLabel;
#property (weak, nonatomic) IBOutlet UIButton *restartButton;
#property(nonatomic, strong) AVAudioPlayer *soundEffects;
#property (weak, nonatomic) IBOutlet UISegmentedControl *clickTypeSegmentedControl;
#end
#implementation GameViewController
#synthesize difficulty, timer, playerName, scoreToAdd, clickTypeSegmentedControl;
double secondsPassed=-1.0f;
int seconds=0;
int totalRowsCols=0, totalMines=0, heightWidth=0, clicKNumber=0;
static NSString * const IMAGE_NAME_FLAG = #"flag.png";
static NSString * const IMAGE_NAME_BOMB_X = #"bomb.png";
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.hidesBackButton = YES;
UIBarButtonItem *backButton =[[UIBarButtonItem alloc]initWithTitle:#"MenĂ¹" style:UIBarButtonItemStyleBordered target:self action:#selector(popAlertAction:)];
self.navigationItem.leftBarButtonItem=backButton;
clickTypeSegmentedControl.selectedSegmentIndex = 0;
rootController = (BombsSeekerViewController *)[self.navigationController.viewControllers objectAtIndex:0];
NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
playerName = [defaults objectForKey:#"NomeGiocatore"];
scoreToAdd = [[NSMutableDictionary alloc]init];
[self createGameBoard:difficulty];
[self newGame:nil];
}
-(void) newGame:(UIButton *)sender {
[self.view.subviews makeObjectsPerformSelector: #selector(removeFromSuperview)];
clicKNumber=0;
secondsPassed=0;
self.timerLabel.text = [self labelString:secondsPassed];
self.game = [[Game alloc] initWithWidth:totalRowsCols AndHeight:totalRowsCols AndMineCount:totalMines];
self.buttonArray = [[NSMutableArray alloc] init];
[self.restartButton addTarget:self action:#selector(newGame:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.restartButton];
[self.view addSubview:self.timerLabel];
[self.view addSubview:self.bombsLabel];
for(int i = 0; i < totalRowsCols; i++) {
for (int j = 0; j < totalRowsCols; j++) {
self.button = [[Tile alloc] initWithLocation: CGPointMake(j,i) andHW:heightWidth andBlock:self.game.board[j][i] andTag:(i*totalRowsCols+j)];
[self.buttonArray addObject:self.button];
[self.view addSubview:self.button];
[self.button addTarget:self action:#selector(click:) forControlEvents:UIControlEventTouchUpInside];
}
}
[self.timer invalidate];
}
- (void) createGameBoard:(int)diff{
switch (diff) {
case 1:
totalRowsCols = 6;
totalMines = 2;
heightWidth = 44;
break;
case 2:
totalRowsCols = 8;
totalMines = 16;
heightWidth = 35;
break;
case 3:
totalRowsCols = 10;
totalMines = 25;
heightWidth = 29;
break;
}
self.flagCount = totalMines;
_bombsLabel.text = [NSString stringWithFormat:#"%d",self.flagCount];
}
-(NSString *) labelString: (int) num {
if(num < 10) {
return [NSString stringWithFormat:#"00%i",num];
}
else if(self.timeCount.intValue < 100) {
return [NSString stringWithFormat:#"0%i",num];
}
else if(self.timeCount.intValue < 1000) {
return [NSString stringWithFormat:#"%i",num];
}
else
return #"---";
}
-(void) click:(Tile *)sender {
if(clicKNumber <1){
[self refreshLabel:self.timer];
self.timer = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:#selector(refreshLabel:)
userInfo:nil
repeats:YES];
clicKNumber++;
}
if(self.game.gameStatus == STATUS_LOST || self.game.gameStatus == STATUS_WON) return;
if (self.clickTypeSegmentedControl.selectedSegmentIndex == 0 && sender.block.marking == MARKING_BLANK) {
[self.game clickedAtColumn: sender.point.x AndRow: sender.point.y];
for(Tile *b in self.buttonArray) {
if(b.block.marking == MARKING_CLICKED) {
b.enabled = NO;
}
else if(b.block.marking == MARKING_BLANK) {
[b setTitle:#"" forState:UIControlStateNormal];
[b setImage:nil forState:UIControlStateNormal];
}
}
}
else if (self.clickTypeSegmentedControl.selectedSegmentIndex == 1){
if(sender.block.marking == MARKING_BLANK && self.flagCount > 0) {
sender.block.marking = MARKING_FLAGGED;
self.flagCount--;
_bombsLabel.text = [NSString stringWithFormat:#"%d",self.flagCount];
[sender setImage:[UIImage imageNamed:IMAGE_NAME_FLAG] forState:UIControlStateNormal];
}
else if(sender.block.marking == MARKING_FLAGGED) {
sender.block.marking = MARKING_BLANK;
self.flagCount++;
_bombsLabel.text = [NSString stringWithFormat:#"%d",self.flagCount];
[sender setImage:[UIImage imageNamed:#"tile.png"] forState:UIControlStateNormal];
}
}
if(self.game.gameStatus == STATUS_LOST) [self gameLost:sender];
else if(self.game.gameStatus == STATUS_WON) [self gameWon];
}
If this is what I think it is, you should not be doing this:
[self.view.subviews makeObjectsPerformSelector: #selector(removeFromSuperview)];
When the viewDidLoad is called, the newGame method is called, which removes al subviews from Superview. Including the ones added in Storyboard.
Make sure controller in storyboard is linked with the right controller class.
You call this method during -viewDidLoad:
-(void) newGame:(UIButton *)sender {
[self.view.subviews makeObjectsPerformSelector: #selector(removeFromSuperview)];
//...
}
Thus, anything you put in your nib is getting removed after it loads.

ScrollView of images in ios

Hi my requirement is showing image in scrollview along with that it should display next and previous button.User can scroll the image as well as use buttons to move images.
I have doubt about how to get the index/tag/imagename or anything else when user scroll based on that values buttons should be updated.
Here is my Code
[self arrayInitiaisation];
scrollview.pagingEnabled = YES;
scrollview.alwaysBounceVertical = NO;
scrollview.alwaysBounceHorizontal = YES;
NSInteger numberOfViews = 4;
for (int i = 0; i < numberOfViews; i++) {
CGFloat xOrigin = i*320;
imageView.image = [UIImage imageNamed:[NSString stringWithFormat:#"image%d",i+1]];
imageView.contentMode = UIViewContentModeScaleAspectFit;
[self.scrollview addSubview:imageView];
imageView.tag = i;
...
Array Initialisation method
-(void) arrayInitialisation {
count=0;
[super viewDidLoad];
images=[NSMutableArray arrayWithObjects : [UIImage imageNamed:#"image1.png"],
[UIImage imageNamed :#"image2.png"],
[UIImage imageNamed :#"image3.png"],
[UIImage imageNamed :#"image4.png"],nil];
[imageView setImage:[images objectAtIndex:0]];
NSLog(#"Array Length :%d",images.count);
[previous setEnabled:NO];
}
Action Methods
- (IBAction)nextButton:(id)sender {}
- (IBAction)prevButton:(id)sender {}
scroll is working correctly but when user clicks on prev and next image is not updating on 'imageview'
Here is my updated code
int count=0;
- (void)viewDidLoad
{
[super viewDidLoad];
[self arrayInitialisation];
[scrollview setScrollEnabled:YES];
self.scrollview =[[UIScrollView alloc] initWithFrame:CGRectMake(30 , 30, 320, 412)];
self.scrollview.delegate=self;
scrollview.pagingEnabled = YES;
scrollview.alwaysBounceVertical=NO;
scrollview.alwaysBounceHorizontal=YES;
scrollview.showsHorizontalScrollIndicator=NO;
NSInteger numberOfViews = 4;
for (int i = 0; i < numberOfViews; i++) {
CGFloat xOrigin = i*320;
imageView = [[UIImageView alloc]initWithFrame:CGRectMake(xOrigin, 0, 320, 412)];
imageView.image = [images objectAtIndex:i];
imageView.contentMode = UIViewContentModeScaleAspectFit;
[self.scrollview addSubview:imageView];
imageView.tag=i;
}
scrollview.contentSize = CGSizeMake(320*numberOfViews, 412);
scrollview.contentOffset = CGPointMake(0,0);
[self.view addSubview:self.scrollview];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
-(void) arrayInitialisation{
count=0;
[super viewDidLoad];
images=[NSArray arrayWithObjects : [UIImage imageNamed:#"image1.png"],
[UIImage imageNamed :#"image2.png"],
[UIImage imageNamed :#"image3.png"],
[UIImage imageNamed :#"image4.png"],nil];
[imageView setImage:[images objectAtIndex:0]];
NSLog(#"Array Length :%d",images.count);
[previous setEnabled:NO];
}
- (IBAction)nextButton:(id)sender {
if(count==0){
count++;
NSLog(#"Next Button : if Loop %d",count);
[imageView setImage:[images objectAtIndex:count]];
[previous setEnabled:YES];
}
else{
[previous setEnabled:YES];
count++;
NSLog(#"Next Button : else Loop %d",count);
if(count <images.count){
[imageView setImage:[images objectAtIndex:count]];
}
else{
[next setEnabled:NO];
}
}
}
- (IBAction)prevButton:(id)sender {
if(count==0){
//count--;
NSLog(#"prev Button : if Loop %d",count);
[imageView setImage:[images objectAtIndex:count]];
[previous setEnabled:NO];
[next setEnabled:YES];
}
else{
count--;
NSLog(#"prev Button : else Loop %d",count);
[imageView setImage:[images objectAtIndex:count]];
[previous setEnabled:YES];
//[next setEnabled:YES];
}
}
#pragma mark - ScrollView Delegate
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate: (BOOL)decelerate{
//NSLog(#"scrollViewDidEndDragging");
/* count=count+1;
NSLog(#"scrollViewDidEndDragging : %d",count);*/
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
//NSLog(#"scrollViewDidScroll");
}
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset NS_AVAILABLE_IOS(5_0){
//NSLog(#"scrollViewWillEndDragging");
count=count+1;
NSLog(#"scrollViewWillEndDragging : %d",count);
}
I have left and right button for scroll images, and imageview width is same.
I am writing code for scroll image at pressing button.
int pos=0;// ViewDiaLoad
- (IBAction)OnClickLeftButton:(UIButton*)sender
{
if(pos>0)
{
pos -=1;
[scrlDemandMenu scrollRectToVisible:CGRectMake(pos*scrlDemandMenu.frame.size.width, 0, scrlDemandMenu.frame.size.width, scrlDemandMenu.frame.size.height) animated:YES];
}
}
- (IBAction)OnClickRightButton:(UIButton*)sender
{
if(pos<numberOfImages)
{
pos +=1;
[scrlDemandMenu scrollRectToVisible:CGRectMake(pos*scrlDemandMenu.frame.size.width, 0, scrlDemandMenu.frame.size.width, scrlDemandMenu.frame.size.height) animated:YES];
}
}
Set scrollView Deleagte
Scroll View delegate Method
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
pos=scrollView.contentOffset.x/scrollView.frame.size.width;
}
You can use UIPageControl and set and get image according to page index. For more information check out this link
Try below piece of code. I hope it will help. Put this in your .h file
IBOutlet UIScrollView *scrollView;
IBOutlet UIPageControl *pageControl;
NSMutableArray *arrImages;
NSInteger page;
Now in your - (void)viewDidLoad put following lines.
int x = 30;
for (int i=0; i< arrImages.count; i++)
{
UIImageView *imgShow = [[UIImageView alloc]initWithFrame:CGRectMake(x+20, 50, self.view.frame.size.width-100, self.view.frame.size.height-180)];
imgShow.backgroundColor = [UIColor whiteColor];
imgShow.image = [UIImage imageNamed:[arrImages objectAtIndex:i]];
imgShow.contentMode = UIViewContentModeScaleAspectFit;
[scrollView addSubview:imgShow];
x = x+scrollView.frame.size.width;
}
scrollView.contentSize = CGSizeMake(5*self.view.frame.size.width, 0);
pageControl.backgroundColor = [UIColor clearColor];
pageControl.pageIndicatorTintColor = [UIColor grayColor];
pageControl.currentPageIndicatorTintColor = [UIColor blueColor];
[pageControl setTintAdjustmentMode:UIViewTintAdjustmentModeDimmed];
pageControl.numberOfPages = arrTitle.count;
pageControl.currentPage = 0;
implement scroll view delegate.
#pragma mark - ScrollView Delegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView1
{
CGFloat pageWidth = scrollView.frame.size.width;
float fractionalPage = scrollView.contentOffset.x / pageWidth;
page = lround(fractionalPage);
pageControl.currentPage = page;
}
- (IBAction)prevButton:(UIButton *)sender
{
page = page-1;
UIButton *btn = (UIButton *)[sender viewWithTag:sender.tag];
// write your code
for (id obj in btn.subviews)
{
if ([obj isKindOfClass:[UIImageView class]])
{
// write your code
}
else
{
// write your code
}
}
}
- (IBAction)nextButton:(UIButton *)sender
{
page = page+1;
UIButton *btn = (UIButton *)[sender viewWithTag:sender.tag];
// write your code
for (id obj in btn.subviews)
{
if ([obj isKindOfClass:[UIImageView class]])
{
// write your code
}
else
{
// write your code
}
}
}

NSArray index beyond bounds error

I have created a simple image browser with two buttons to view the next and the previous images.
Here's the code.
#import "ViewController.h"
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UIImageView *imageView;
#property (strong, nonatomic) NSArray *images;
#property (assign, nonatomic) NSInteger imageIndex;
#property (strong, nonatomic) UIBarButtonItem *nextButton;
#property (strong, nonatomic) UIBarButtonItem *prevButon;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Adding Next and Previous buttons
self.nextButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"next"] style:UIBarButtonItemStylePlain target:self action:#selector(nextButtonPressed)];
self.prevButon = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"previous"] style:UIBarButtonItemStylePlain target:self action:#selector(previousButtonPressed)];
self.navigationItem.rightBarButtonItems = #[self.nextButton, self.prevButon];
// Loading images
self.images = #[
[UIImage imageNamed:#"1"],
[UIImage imageNamed:#"2"],
[UIImage imageNamed:#"3"],
[UIImage imageNamed:#"4"],
[UIImage imageNamed:#"5"],
[UIImage imageNamed:#"6"],
[UIImage imageNamed:#"7"],
[UIImage imageNamed:#"8"],
[UIImage imageNamed:#"9"]
];
self.imageIndex = 0;
self.imageView.image = self.images[self.imageIndex];
}
- (void)nextButtonPressed
{
self.imageIndex++;
self.imageView.image = self.images[self.imageIndex];
}
- (void)previousButtonPressed
{
self.imageIndex--;
self.imageView.image = self.images[self.imageIndex];
}
#end
My problem is say if I tap next button after the last image or previous button when the first image, it'll throw a index beyond bounds error.
How can I stop this from happening?
Thank you.
You have to check whether the index is present in your index.
You can make the verification in your nextButtonPressed and previousButtonPressed methods:
- (void)nextButtonPressed
{
if (imageIndex < ([self.images count] - 1))
{
self.imageIndex++;
self.imageView.image = self.images[self.imageIndex];
}
}
- (void)previousButtonPressed
{
if (imageIndex >= 1)
{
self.imageIndex--;
self.imageView.image = self.images[self.imageIndex];
}
}
For information the NSArray raises an NSRangeException if the index is beyond the end of the array (see the documentation).
You are keeping track of the current image index, which is good, because you can use that to check if there is a next image or a previous by using the image arrays count property.
- (void)nextButtonPressed
{
if ( self.imageIndex < self.images.count - 1) {
self.imageIndex++;
self.imageView.image = self.images[self.imageIndex];
}
}
- (void)previousButtonPressed
{
if ( self.imageIndex > 0 ) {
self.imageIndex--;
self.imageView.image = self.images[self.imageIndex];
}
}
Another alternative is starting over when you reach the last image.
- (void)nextButtonPressed
{
if ( self.imageIndex < self.images.count - 1) {
self.imageIndex++;
} else {
self.imageIndex = 0
}
self.imageView.image = self.images[self.imageIndex];
}
- (void)previousButtonPressed
{
if ( self.imageIndex > 0 ) {
self.imageIndex--;
} else {
self.imageIndex = self.images.count - 1;
}
self.imageView.image = self.images[self.imageIndex];
}
You can use modulus like this - so it wraps around on itself.
This way you never need to disable buttons and it also makes it easier for the user to get from one end of the list to the other more efficiently.
replace the following line
self.imageIndex++;
with
self.imageIndex = (self.imageIndex + 1) % [self.images count];
and where you have the following line
self.imageIndex--;
replace with
self.imageIndex = (self.imageIndex + [self.images count] - 1) % [self.images count];
A good UI habit will be to disable the next (or previous) button once you reach the last image (and of course prevent the overflow in the array):
- (void)nextButtonPressed
{
self.imageIndex++;
self.imageView.image = self.images[self.imageIndex];
[self.previousButton setEnabled:YES];
if (self.imageIndex == [self.images count] - 1) {
[self.nextButton setEnabled:NO];
return ;
}
}
- (void)previousButtonPressed
{
self.imageIndex--;
self.imageView.image = self.images[self.imageIndex];
[self.nextButton setEnabled:YES];
if (self.imageIndex == 0) {
[self.previousButton setEnabled:NO];
return ;
}
}
Since you start with index = 0 you should disable the previous button in viewDidLoad method (as you do not have more previous images until you press next) or do it directly in IB if possible

Resources