How change value of segmentedcontrol by swipegesture?
"Invalid parameter not satisfying: selectedSegmentIndex < (NSInteger)self._items.count"
- (void)updateSelectedSegmentText
{
int theSegmentIndex = [_segmentedControl selectedSegmentIndex];
NSDictionary *theInfo = [self.top.segments objectAtIndex:theSegmentIndex];
self.bioTextView.text = [NSString stringWithFormat:#"%#", theInfo [#"sData"]];
[self.bioTextView scrollRangeToVisible:NSMakeRange(0, 0)];
}
- (void)swipe:(UISwipeGestureRecognizer *)swipeRecogniser
{
s = 1;
if ([swipeRecogniser direction] == UISwipeGestureRecognizerDirectionLeft)
{
self.segmentedControl.selectedSegmentIndex -=s;
[self updateSelectedSegmentText];
}
else if ([swipeRecogniser direction] == UISwipeGestureRecognizerDirectionRight)
{
self.segmentedControl.selectedSegmentIndex +=s;
[self updateSelectedSegmentText];
}
}
You need to first check if the new index is valid. You cannot go to the left if you are already on the first tab and you cannot go to the right if you are on the last tab. So you need to first calculate the new index and then check if it is in range before you set the selectedSegmentIndex property:
NSInteger index = self.segmentedControl.selectedSegmentIndex;
if ([swipeRecogniser direction] == UISwipeGestureRecognizerDirectionLeft) {
--index;
} else if ([swipeRecogniser direction] == UISwipeGestureRecognizerDirectionRight) {
++index;
}
if (0 <= index && index < self.segmentedControl.numberOfSegments) {
self.segmentedControl.selectedSegmentIndex = index;
[self updateSelectedSegmentText];
}
Related
I'm using MBXPageViewController as a UIPageViewController.
I'm trying to make the app more accessible with the UIAccessibilityScrollDirection method.
This works almost fine, but has a couple of issues:
The scrollDirection makes 2 steps to the right at first. I've logged it and give a currentIndex from 0 -> 2.
The scrollDirection won't go back to the first childViewController, the currentIndex 0. Voice-over tells there is no object left.
Here is how the accessibilityScroll method look like.
The setPageControllerForIndex:(NSInteger)index direction:(UIPageViewControllerNavigationDirection)direction currentMBXViewController:(id)weakSelf destionation:(NSInteger)destination method is described here
-(BOOL)accessibilityScroll:(UIAccessibilityScrollDirection)direction {
__weak __typeof(&*self)weakSelf = self;
NSInteger tempIndex = _currentPageIndex;
NSLog(#"%ld", (long)tempIndex);
if (direction == UIAccessibilityScrollDirectionRight) {
//Previous Page
if (direction < tempIndex) {
NSLog(#"links");
for (int i = (int)tempIndex-1; i >= direction; i--) {
[self setPageControllerForIndex:i direction:UIPageViewControllerNavigationDirectionReverse currentMBXViewController:weakSelf destionation:direction];
NSLog(#"%d", i);
}
NSLog(#"%ld", direction);
UIAccessibilityPostNotification(UIAccessibilityPageScrolledNotification, #"links");
}
} else if (direction == UIAccessibilityScrollDirectionLeft) {
//Next Page
if (direction > tempIndex) {
NSLog(#"rechts");
for (int i = (int)tempIndex+1; i <= direction; i++) {
[self setPageControllerForIndex:i direction:UIPageViewControllerNavigationDirectionForward currentMBXViewController:weakSelf destionation:direction];
NSLog(#"%d", i);
}
NSLog(#"%ld", direction);
UIAccessibilityPostNotification(UIAccessibilityPageScrolledNotification, #"rechts");
}
}
UIAccessibilityPostNotification(UIAccessibilityPageScrolledNotification, nil);
return YES;
}
An example is the assignment 3 from stanford's cs193p:
-(int)match:(NSArray *)otherCards
{
int score = 0;
if ([otherCards count] == 1)
{
playingCard *otherCard = [otherCards firstObject];
if ([self.suit isEqualToString: otherCard.suit])
{
score = 1;
NSLog(#"%d",score);
}else if (self.rank == otherCard.rank)
{
score = 4;
}
}
return score;
}
The above is the implementation of a method in a subclass of Cards called PlayingCard.
- (int)match:(NSArray *)otherCards
{
int score = 0;
for (Card *cards in otherCards)
if ([cards.contents isEqualToString:self.contents])
score = 1;
return score;
}
The above is the implementation of match in Cards.
-(void)chooseCardAtIndex:(NSUInteger)index
{
Card *card = [self cardAtIndex:index];
if (!card.isMatched)
{
if (card.isChosen)
{
card.chosen = NO;
}
else
{
for (Card *otherCard in self.cards)
{
if (otherCard.isChosen && !otherCard.isMatched)
{
int matchScore = [card match:#[otherCard]];
if (matchScore)
{
self.score += matchScore * MATCH_BONUS;
card.matched = YES;
otherCard.matched = YES;
}
else
{
otherCard.chosen = NO;
self.score -= MISMATCH_PENALTY;
}
break;
}
}
self.score -= COST_TO_CHOOSE;
card.chosen = YES;
}
}
}
As you can see above, the method match is called by an instance of Card and not playingCard, yet the results follow implementation from playingCard
I think you need a virtual base class ,in superClass cards
-(int)match:(NSArray *)otherCards
{
// do nothing
}
and you need two subclass such as PlayingCard ,NormalCard .YOU Should implementation the function in each subClass.
I created a tutorial by some consequential images and added a page control on it. In addition, I added a swipe gesture which responds by changing the picture. In the code below, a switch case is defined in order to decide which image and dot should be the next according to the direction of swiping (left/right).
- (IBAction)handleSwipe:(UISwipeGestureRecognizer *)sender
{
// NSLog(#"swiped");
NSArray *images;
if (self.selectedRow == 0) {
images = [[NSArray alloc] initWithObjects:#"w8.JPG",#"w7.JPG",#"w6.JPG",#"w5.JPG",#"w4.JPG",#"w3.JPG", #"w2.JPG", #"w1.JPG" ,#"w9.JPG", nil];
self.pageControl.hidden = NO;
[self.pageControl setNumberOfPages:9];
UISwipeGestureRecognizerDirection direction = [(UISwipeGestureRecognizer *) sender direction];
switch (direction) {
case UISwipeGestureRecognizerDirectionRight:
if (pageController == 0 || imageIndex == 8)
{
self.Oops = [[UIAlertView alloc] initWithTitle:#"Oops!" message:#"You cannot swipe to the left, there are not any previous steps." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[self.Oops show];
}
else {
[self.pageControl setCurrentPage:pageController - 1];
pageController = pageController - 1;
}
imageIndex++;
break;
case UISwipeGestureRecognizerDirectionLeft:
if (pageController < 8 && pageController >= 0) {
[self.pageControl setCurrentPage:pageController];
pageController = pageController + 1;
}
else {
[self.pageControl setCurrentPage: pageController ];
pageController = 0;
}
imageIndex--;
break;
default:
break;
}
NSLog(#"pagecontroller is %li and imageIndex is %li " , pageController, imageIndex);
imageIndex = (imageIndex < 0) ? ([images count] - 1): imageIndex % [images count];
self.imageView.image = [UIImage imageNamed:[images objectAtIndex:imageIndex]];
}
As you see in the code, there is a NSLog; when I run the app, everything works properly but when I swipe to the right to see a previous image, Although NSLog shows that all indexes of dots and images change correctly and we see the previous image, the dots don't change. Swiping to the right again, the dots change but it's late because the order of the images and dots that must be classified becomes disordered for example the last image is shown with the first dot.
I'm sure that my algorithm is correct, because I checked it with that NSLog, and also everything works fine before swiping to the right.
Any ideas?
I have changed the code a bit:
switch (direction) {
case UISwipeGestureRecognizerDirectionRight:
if (pageController != 0 && imageIndex != 9) {
[self.pageControl setCurrentPage:(pageController - 1)];
pageController --;
imageIndex++;
}
break;
case UISwipeGestureRecognizerDirectionLeft:
if (pageController <= 8 && pageController >= 0) {
[self.pageControl setCurrentPage:pageController];
pageController = pageController + 1;
imageIndex--;
}
break;
default:
break;
}
Now the only problem is that the page control counts the current dot twice when I swipe to a different direction.
Your imageIndex++ and imageIndex-- lines are in the wrong place. (You presumably don't want to change image if pageController is already 0, for example). Move them to:
- (IBAction)handleSwipe:(UISwipeGestureRecognizer *)sender
{
// NSLog(#"swiped");
NSArray *images;
if (self.selectedRow == 0) {
images = [[NSArray alloc] initWithObjects:#"w8.JPG",#"w7.JPG",#"w6.JPG",#"w5.JPG",#"w4.JPG",#"w3.JPG", #"w2.JPG", #"w1.JPG" ,#"w9.JPG", nil];
self.pageControl.hidden = NO;
[self.pageControl setNumberOfPages:9];
UISwipeGestureRecognizerDirection direction = [(UISwipeGestureRecognizer *) sender direction];
switch (direction) {
case UISwipeGestureRecognizerDirectionRight:
if (pageController == 0 || imageIndex == 8)
{
self.Oops = [[UIAlertView alloc] initWithTitle:#"Oops!" message:#"You should turn over to the left." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[self.Oops show];
}
else {
[self.pageControl setCurrentPage:pageController - 1];
pageController = pageController - 1;
imageIndex++;
}
break;
case UISwipeGestureRecognizerDirectionLeft:
if (pageController < 8 && pageController >= 0) {
[self.pageControl setCurrentPage:pageController];
pageController = pageController + 1;
imageIndex--;
}
else {
[self.pageControl setCurrentPage: pageController ];
pageController = 0;
}
break;
default:
break;
}
NSLog(#"pagecontroller is %li and imageIndex is %li " , pageController, imageIndex);
imageIndex = (imageIndex < 0) ? ([images count] - 1): imageIndex % [images count];
self.imageView.image = [UIImage imageNamed:[images objectAtIndex:imageIndex]];
}
In your amended code, I think you need to set the page control differently (to pageController+1) for swipe left:
switch (direction) {
case UISwipeGestureRecognizerDirectionRight:
if (pageController != 0 && imageIndex != 9) {
[self.pageControl setCurrentPage:(pageController - 1)];
pageController --;
imageIndex++;
}
break;
case UISwipeGestureRecognizerDirectionLeft:
if (pageController <= 8 && pageController >= 0) {
[self.pageControl setCurrentPage:pageController+1];
pageController = pageController + 1;
imageIndex--;
}
break;
default:
break;
}
I am calling a view with method;
[self.storyboard instantiateViewControllerWithIdentifier:];
Yesterday, this method was working well, but after some time something happened, it has stopped working.
I am using both xCode6 beta 6 and xcode5 v5.1.1
My code is as below, here all objects of an ViewController is nil?
What is wrong with this?
(IBAction)addTemplateViewPressed:(id)sender
{
PhotoTemplateViewController *templateVC = [self.storyboard instantiateViewControllerWithIdentifier:#"photoTemplateViewController"];
//NSLog(#"%#",NSStringFromCGRect(templateVC.view.frame));
if(photoVerticalArray.count !=0 )
{
photoVerticalArray = [templateVC setVerticalImages:photoVerticalArray];
}
else
{
verticalFinished = true;
}
if(photoHorizontalArray.count !=0)
{
photoHorizontalArray = [templateVC setHorizontalImages:photoHorizontalArray];
}
else
{
horizontalFinished = true;
}
if(!verticalFinished && !horizontalFinished)
{
CGRect temp = templateVC.mainView.frame;
if(lastPosition == 0)
{
temp.origin.y = lastPosition = templateVC.mainView.frame.origin.y+48;
}
else
{
lastPosition = temp.origin.y= lastPosition + temp.size.height-4;
}
templateVC.view.frame = temp;
[mainView addSubview:templateVC.view];
NSLog(#"%#",NSStringFromCGSize(mainScrollView.contentSize));
[mainScrollView setContentSize:CGSizeMake(0, temp.origin.y+temp.size.height+50)];
NSLog(#"%#",NSStringFromCGSize(mainScrollView.contentSize));
}
I am using iOS 5 to implement an app.
In this app I have 4 button, each button triggers an animation to unhide a UIView. However, if I press a button and then another, the view that appeared first should disappear and the view for the new button would appear.
I have this working so far. But if the user taps two buttons rapidly it will display the two views. How can I insure that only once touch event is processed?
The action for the button is something like:
- (void)buttonPressed:(id)sender
{
MenuButton *aButton = (MenuButton *)sender;
switch (aButton.tag) {
case 0:
if (displayingView && currentlyDisplayingView != picker1)
[self toggleView:currentlyDisplayingView atIndex:currentIndex];
[self toggleView:picker1 atIndex:aButton.tag];
currentlyDisplayingView = picker1;
currentIndex = aButton.tag;
break;
case 1:
if (displayingView && currentlyDisplayingView != picker2)
[self toggleView:currentlyDisplayingView atIndex:currentIndex];
[self toggleView:picker2 atIndex:aButton.tag];
currentlyDisplayingView = picker2;
currentIndex = aButton.tag;
break;
case 2:
if (displayingView && currentlyDisplayingView != picker3)
[self toggleView:currentlyDisplayingView atIndex:currentIndex];
[self toggleView:picker3 atIndex:aButton.tag];
currentlyDisplayingView = picker3;
currentIndex = aButton.tag;
break;
default:
break;
}
NSLog(#"Pressed %#",[buttonNames objectAtIndex:aButton.tag]);
}
And the animation code:
- (void)toggleView:(UIView *)picker
atIndex:(NSInteger)index
{
if (picker) {
picker.hidden = NO;
[UIView animateWithDuration:0.5
animations:^{
picker.alpha = abs(picker.alpha - 1);
CGRect rect = picker.frame;
if (rect.size.height == 0){
rect.size.height = 76;
} else if (rect.size.height == 76) {
rect.size.height = 0;
}
picker.frame = rect;
for (int i = index+1; i < [viewButtons count]; i++) {
UIButton *aButton = [viewButtons objectAtIndex:i];
CGRect frame = aButton.frame;
if (rect.size.height == 0){
frame.origin.y -= 75;
} else if (rect.size.height == 76) {
frame.origin.y += 75;
}
aButton.frame = frame;
}
}
completion:^(BOOL success){
if (picker.alpha == 0){
picker.hidden = YES;
} else if (picker.alpha == 1) {
picker.hidden = NO;
}
displayingView = !displayingView;
}];
}
}
Call beginIgnoringInteractionEvents before calling animateWithDuration, and call endIgnoring... in the completion handler.