UIScrollView costum pagination size - ios

first take a look on this picture from localScope app :
i have 2 (simple?) questions :
how can i paginate my icons like this?
how can i detect witch icon is " selected "
thank you.

Answer to the first question: You have to make your scroll view as big as the page size, enable its pagingEnabled property, then somehow make it to display elements and respond to touches outside of its bounds. See this code and these links:
#interface SmallPagedScrollView: UIScrollView <UIScrollViewDelegate> {
UIEdgeInsets responseInsets;
NSMutableArray *items;
}
#implementation SmallPagedScrollView
#synthesize responseInsets;
- (id)init
{
if ((self = [super initWithFrame:CGRectMake(x, y, w, h)]))
{
self.backgroundColor = [UIColor clearColor];
self.pagingEnabled = YES;
self.showsHorizontalScrollIndicator = NO;
self.showsVerticalScrollIndicator = NO;
self.clipsToBounds = NO;
CGFloat hInset = 3 * self.width / 2;
self.responseInsets = UIEdgeInsetsMake(0.0f, hInset, 0.0f, hInset);
self.delegate = self;
items = [[NSMutableArray alloc] init];
}
return self;
}
- (void)dealloc
{
[items release];
[super dealloc];
}
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
CGPoint parentLocation = [self convertPoint:point toView:self.superview];
CGRect responseRect = self.frame;
responseRect.origin.x -= self.responseInsets.left;
responseRect.origin.y -= self.responseInsets.top;
responseRect.size.width += self.responseInsets.left + self.responseInsets.right;
responseRect.size.height += self.responseInsets.top + self.responseInsets.bottom;
return CGRectContainsPoint(responseRect, parentLocation);
}
See also Paging UIScrollView in increments smaller than frame size (Split's answer)
Answer to the second question: you can calculate the selected page using this formula:
int selectedIndex = (scrollView.contentOffset + scrollView.size.width / 2) / scrollView.size.width;

Well one clean & memory efficient approach is to have a UINavigationController & UIToolBar like so -
When the user taps on any button in the UIToolBar invoke that particular viewController by popping and pushing them.
I hope its clear that the look and feel can be achieved close to what you are showing in the image, I am talking about the functionality.

Related

initWithImage works fine initWithFrame is being called more than once

I am sublassing either an UIImageView or UIView for generating simple color tiles with digits. If I am using UIImageView, I use initWithImage method. If I use UIView, the method initWithFrame is being used.
Either red square image or programmatically generated red view is used for initialization.
The problem can be seen on two screenshots: when initWithImage is being used - everything works fine. If initWithFrame method is being used, I am ending with multiple white views without any information created in even order with normal views. All the screenshots and code attached.
This how it looks when initializing using initWithImage:
- (id)initWithImage:(UIImage *)image {
self = [super initWithImage:image];
if (self) {
//Some non-important, label-related stuff.
[self addSubview:self.numberLabel];
}
return self;
}
And this is how it looks with initWithFrame:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.redView = [self redViewWithFrame:frame];
[self addSubview:self.redView];
//label-related stuff
}
return self;
}
- (UIView *)redViewWithFrame:(CGRect)frame {
UIView *view = [[UIView alloc] initWithFrame:frame];
view.backgroundColor = [UIColor redColor];
view.alpha = 1;
return view;
}
And the for-loop, calling these initializers from another class (UIScrollView subclass). The label value is being set after the view had been initialized.
- (void)setNumberOfBlocks:(NSInteger)numberOfBlocks {
_blocks = [[NSMutableArray alloc] init];
CGSize contentSize;
contentSize.width = BLOCK_WIDTH * (numberOfBlocks);
contentSize.height = BLOCK_HEIGHT;
self.contentSize = contentSize;
for (int i = 0; i < numberOfBlocks; i++) {
CGFloat totalWidth = BLOCK_WIDTH * i;
CGRect frame = CGRectMake(0, 0, BLOCK_WIDTH, BLOCK_HEIGHT);
frame.origin.x = totalWidth;
BlockView *view = [[BlockView alloc] initWithImage:[UIImage imageNamed:#"block.png"]];
OR!!!
BlockView *view = [[BlockView alloc] initWithFrame:frame];
view.frame = frame;
NSString *number = [NSString stringWithFormat:#"%ld", (long)i + 1];
view.numberLabel.text = number;
[self addSubview:view];
[_blocks addObject:view];
}
}
Googling gave me the impression that this is very common problem, but I haven't found any solution how to beat this. Moreover, I still do not understand, why numbers are in totally right order, the only problem is view position.
The problem is that you're setting the frame of the red view to the superview's frame instead of its bounds. Since the red view is a subview of the BlockView, its frame needs to be relative to its superview, which you get with bounds (its not clear why you even need the red view, as opposed to setting the background color of the block view to red).
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.redView = [self redViewWithFrame:self.bounds];
[self addSubview:self.redView];
//label-related stuff
}
return self;
}
I think you should set the frame origin to (0,0) in redViewWithFrame in ordre to hâve superposed views

Multiple UIScrollViews as child view controller's in UIScrollView not scrolling to top

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.

How to make table scrolling work: UIControl within UITableView within UIControl

Here's the setup: I have UIControls in table cells that allow sliding from right to left for a delete function (like Clear)
The table cells live inside a UITableView.
The TableView lives inside another UIControl that allows swiping from left to right or right to left in order to change days. When this happens a new TableView gets created to the right or left of the main one, and the new one is pulled in from left or right until a threshold is met and an animation takes over and then replaces the old with the new.
In some conditions all of these interactions actually work correctly. The issue is that after a couple of interactions (table slides seem to be problematic) it becomes difficult / impossible to scroll the table.
Here is the code for the TableViewSlider (the top level UIControl that contains the TableViews). Any ideas would be greatly appreciated!
#implementation OSETableViewSlider
- (void) initialize {
self.backgroundColor = [UIColor backgroundFlatColor];
self.mainTableView = [self createUITableView];
self.mainTableView.frame = CGRectMake(0,0, self.frame.size.width, self.frame.size.height);
self.mainTableView.hidden = NO;
[self addSubview:self.mainTableView];
self.transitionInProgress = NO;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self initialize];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if(self) {
[self initialize];
}
return self;
}
- (UITableView *)createUITableView {
UITableView *newTable = [[UITableView alloc] init];
newTable.hidden = YES;
newTable.separatorStyle = UITableViewCellSeparatorStyleNone;
newTable.scrollEnabled = YES;
newTable.bounces = YES;
newTable.dataSource = self;
newTable.delegate = self;
newTable.backgroundColor = [UIColor backgroundFlatColor];
return newTable;
}
- (void)setFrame:(CGRect)frame {
super.frame = frame;
self.mainTableView.frame = CGRectMake(0,0, frame.size.width, frame.size.height);
}
- (void)transitionToDate:(NSDate *)date fromRight:(BOOL)rightToLeft {
[self.viewController beginTransitionToDate:date];
self.transitionTableView = [self createUITableView];
self.transitionTableView.frame = CGRectMake( rightToLeft ? self.frame.size.width : (-1 * self.frame.size.width), 0,
self.frame.size.width, self.frame.size.height );
self.transitionTableView.hidden = NO;
[self addSubview:self.transitionTableView];
self.transitionInProgress = YES;
[UIView animateWithDuration:0.2f animations:^{
self.transitionTableView.frame = CGRectMake(0,0, self.frame.size.width, self.frame.size.height);
self.mainTableView.frame = CGRectMake( rightToLeft ? (-1 * self.frame.size.width) : self.frame.size.width, 0,
self.frame.size.width, self.frame.size.height);
} completion:^(BOOL completed){
[self.viewController endTransitionDidChange:YES];
[self.mainTableView removeFromSuperview];
self.mainTableView = self.transitionTableView;
self.transitionInProgress = NO;
}];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.viewController activityCountForTransition:(tableView!=self.mainTableView)];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
return [self.viewController cellNumber:indexPath.item forTransition:(tableView!=self.mainTableView)];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return [self.viewController cellNumber:indexPath.item forTransition:(tableView!=self.mainTableView)].frame.size.height;
}
- (void)layoutSubviews {
if(!self.transitionInProgress) {
[self.mainTableView setFrame:CGRectMake(0,0, self.frame.size.width, self.frame.size.height)];
}
}
- (BOOL) beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
NSLog(#"begin track");
self.locationInView = [touch locationInView:self.superview];
self.fingerTracking = YES;
self.fingerMoved = NO;
self.transitionTableView = nil;
return YES;
}
- (CGFloat) calcOffsetForTouch:(UITouch *)touch {
CGFloat fingerOffset = [touch locationInView:self.superview].x - self.locationInView.x;
return fingerOffset + self.startingOffset;
}
- (BOOL) continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
self.fingerMoved = YES;
CGFloat offset = [self calcOffsetForTouch:touch];
//NSLog(#"offset is: %f flarb: %f", offset, fabs(offset));
if(offset < 0 && (!self.transitioningLeft || [OSEUtils isNull:self.transitionTableView])) {
[self.viewController beginTransitionToDate:[OSEUtils daysOffset:1 fromDate:self.viewController.selectedDate withTimeZone:[NSTimeZone timeZoneWithName:#"UTC"]]];
[self.transitionTableView removeFromSuperview];
self.transitionTableView = [self createUITableView];
self.transitioningLeft = YES;
NSLog(#"going left");
[self addSubview:self.transitionTableView];
[self.transitionTableView reloadData];
}
if(offset > 0 && (self.transitioningLeft || [OSEUtils isNull:self.transitionTableView])) {
[self.viewController beginTransitionToDate:[OSEUtils daysOffset:-1 fromDate:self.viewController.selectedDate withTimeZone:[NSTimeZone timeZoneWithName:#"UTC"]]];
[self.transitionTableView removeFromSuperview];
self.transitionTableView = [self createUITableView];
self.transitioningLeft = NO;
NSLog(#"going right");
[self addSubview:self.transitionTableView];
[self.transitionTableView reloadData];
}
CGFloat mult = self.transitioningLeft ? 1 : -1;
if(fabs(offset) > (self.frame.size.width / 3.0f)) {
if(self.transitioningLeft) {
offset = -1 * self.frame.size.width;
} else {
offset = self.frame.size.width;
}
[UIView animateWithDuration:0.2f animations:^{
self.mainTableView.frame = CGRectMake(offset, 0, self.frame.size.width, self.frame.size.height);
self.transitionTableView.frame = CGRectMake(offset + (mult * self.frame.size.width), 0,
self.frame.size.width, self.frame.size.height);
} completion:^(BOOL finished) {
[self.mainTableView removeFromSuperview];
if(self.transitioningLeft) {
[self.viewController.daySelector jumpToNext];
} else {
[self.viewController.daySelector jumpToPrevious];
}
self.mainTableView = self.transitionTableView;
self.transitionTableView = nil;
[self.viewController endTransitionDidChange:YES];
}];
return NO;
}
self.mainTableView.frame = CGRectMake(offset, 0, self.frame.size.width, self.frame.size.height);
self.transitionTableView.frame = CGRectMake(offset + (mult * self.frame.size.width), 0, self.frame.size.width, self.frame.size.height);
self.transitionTableView.hidden = NO;
return YES;
}
- (void) endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
NSLog(#"end tableslide track");
[UIView animateWithDuration:0.2f animations:^{
self.mainTableView.frame = CGRectMake(0,0,self.frame.size.width, self.frame.size.height);
self.transitionTableView.frame = CGRectMake(((self.transitioningLeft ? 1 : -1 ) * self.frame.size.width), 0, self.frame.size.width, self.frame.size.height);
} completion:^(BOOL completion){
[self.transitionTableView removeFromSuperview];
self.transitionTableView = nil;
[self.viewController endTransitionDidChange:NO];
}];
self.fingerTracking = NO;
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
UIView *tableHitTest = [self.mainTableView hitTest:point withEvent:event];
if([tableHitTest isKindOfClass:[OSECellPanelControl class]]) {
return tableHitTest;
} else {
return self;
}
}
#end
Why are you creating a new UITableView when the user swipes left or right? It would be much more efficient to use the built-in deleteRowsAtIndexPath: and insertRowsAtIndexPath: methods to animate the rows sliding in and out without having to slide in and out entire UITableView's.
You can take a look at this for a reference on animating the tableview content changes as you swipe across dates.
I don't know about your current set up, but when I tried this exact same thing with swipeable UITableViewCell's and it's superview being swipe able, I had issues with getting the interaction that I wanted. If this is contributing to your problem, you can look at detecting where the user swipes. If the user swipes within a specific offset from the left and right edge of the UITableViewCell, then it swipes the cell, anything outside of that offset (center of the cell) would have the UITableView itself swiped. You would then animate out the deleting and insertion of the new rows.
Also, by re-instancing a new UITableView each time, you are forcing your UITableViewCell's to be re-instanced each time as well. By using the delete and insert methods, you can continue to use your existing cells via the dequeueReusableCellWithIdentifier method. Each time you re-instance the UITableView, your cells are set to nil and discarded requiring the new tableview to create complete new instances of your cells. This is extremely inefficient.
You're getting in deep with touch tracking and hit detection. Use a higher level API instead - gesture recognisers. With gestures you can set precedence (this one has to fail before this one can begin).
So, you want a couple of custom gestures on the container view (which no longer needs to be a control). These fail if the initial touch point isn't at the edge of the view (within some bound). These trigger the overall table view change.
And the table cells have swipe gestures that each require the custom ones to fail. These trigger your cell deletion logic.
Your idea share a few similarities with how the iOS7 unlock screen and calendar is built. In the unlock screen, you can swipe on notifications, move the notification list up and down, and swipe to unlock. In the calendar app, you can swipe to change the current day, or swipe the header to change the week. Thus I recommend watching the WWDC 2013 Session video #217 "Exploring Scroll Views on iOS 7" that explain and demonstrate how they have done it, and how to replicate the functionality.
Basically, what you could do (and what they did for the unlock screen and calendar screen) is: Either (A) nest UIScrollViews in a UITableView OR (B) use a swipe/pan gesture delegate on every cells, and (C) nest that UITableView along with every other UITableViews representing days in a UIScrollView with paging control enabled.
(A) will allow you to expose a delete button in cells. You could either put the delete button under the UIScrollView that sits in the cell in a way that sliding the content uncover it.
(B) will allow you to track a gesture in cells, cancel it if required, and play with the cell's contentView to display a delete button.
(C) will allow you to swipe from one UITableView to another quite easily, and with paging enable you will get a free "snap into place or bounce back" animation PLUS you can easily reuse two UITableViews instead of allocating one per day.
Personally, I would go with (B) and (C).
Turns out there was a problem with my hitTest method. Replacing [self.mainTableView hitTest...] with [super hitTest...] solved my problem. I think I was messing up some coordinates that was causing this method to return nil when it should have returned a view. I'm not 100% sure exactly what is wrong with it, but it does work better now.

Rotate images with single tap gesture in XCode

So, I'm working in Xcode 5, OS X Mavericks. I have storyboard with one view in it in my project. Programmatically, I have added about 384 UIImageViews in loop in my view. Here's my code I used for it:
-(void)setImageViewsImages {
[self create Randoms]; //it creates random numbers for definition of rotation direction (rn)
for (i = 0; i < 480; i++) {
currentImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"image.png"]];
currentImage.frame = CGRectMake(x, y, 20, 20);
if (rn == 1) {
CGAffineTransform imageRotation = CGAffineTransformMakeRotation(0);
currentImage.transform = imageRotation;
} else {
switch (rn) {
case 2: {
CGAffineTransform imageRotation = CGAffineTransformMakeRotation(M_PI * 0.5);
currentImage.transform = imageRotation;
}
break;
case 3: {
CGAffineTransform imageRotation = CGAffineTransformMakeRotation(M_PI);
currentImage.transform = imageRotation;
}
break;
case 4: {
CGAffineTransform imageRotation = CGAffineTransformMakeRotation(M_PI * 1.5);
currentImage.transform = imageRotation;
}
break;
}
}
[self.view addSubview:currentImage];
x = x + 20;
if (x == 320) {
x = 0;
y = y + 20;
}
}
}
So, what my question is: I want to add a single tap gesture recognizer onto each created image, and then, when all images are in their places, I want to have opportunity to rotate each image right (or left, it doesn't matter) with single tap on it. I wrote this code, and put it in my loop just before [self.view addSubview:currentImage];, :
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(didSingleTap:)];
singleTap.numberOfTapsRequired = 1;
[currentImage addGestureRecognizer:singleTap];
but I can't understand, where to go further.
Thanks for help in advance and sorry for my bad English, hope you will be able to understand it.
Basically the only link you're now missing is an access to the imageView instance from the didSingleTap:. The right way IMO would be subclassing UIImageView, instantiate your subclasses instead and when adding the UITapGestureRecognizer to it calling a method in the subclass instance. Most proper approach would be to delegate the callback back to your view controller like so:
.h
#class RotatingImageView;
#protocol RotatingImageViewDelegate <NSObject>
#required
-(void) rotatingImageViewWasTapped:(RotatingImageView*) rotatingImageView;
#end
#interface RotatingImageView : UIImageView
#property (nonatomic,weak) id<RotatingImageViewDelegate> delegate;
-(void) onTap:(UITapGestureRecognizer*) sender;
#end
.m
#implementation RotatingImageView
- (id)initWithImage:(UIImage *)image
{
self = [super initWithImage:image];
if (self) {
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(onTap:)];
singleTap.numberOfTapsRequired = 1;
[self addGestureRecognizer:singleTap];
}
return self;
}
-(void)onTap:(UITapGestureRecognizer *)sender
{
[self.delegate rotatingImageViewWasTapped:self];
}
#end
your view controller would then implement the RotatingImageViewDelegate protocol, assign itself as a delegate of each RotatingImageView instance and on each tap it would receive the rotatingViewWasTapped: callback with the appropriate image view in the parameter. You could either do the logic directly in the onTap: method inside the subclass or handle it in your view controller.
Why are you recreating the logic of a UICollectionView?
You stated you are on mavericks so iOS 5 support is not an issue.
My advice would be to create a UICollectionViewController, use the UICollectionViewFlowLayout with a itemSize of 20, 20 and create a custom cell.
In the setSelected method, transform the image as such:
- (void)setSelected:(BOOL)selected;
{
[super setSelected:selected];
self.imageView.transform = CGAffineTransformMakeRotation((arc4random() % 4) * M_PI);
}

UIStepper issue: decrements but won't increment

I have a weird issue with a UIStepper (and it's accompanying UITextField)
Consider this code snippet:
#interface LTRPageTracker : UIView <UITextFieldDelegate>
{
UIStepper* page_move;
UITextField* page_no_view;
}
-(void) nextOrPrevPage:(id)sender forEvent:(UIControlEvents) event;
#implementation LTRPageTracker
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
CGRect stepperFrame, pageNoframe;
pageNoframe.origin = frame.origin;
pageNoframe.size.height = frame.size.height;
pageNoframe.size.width = frame.size.width/2;
stepperFrame.origin.x = pageNoframe.origin.x + pageNoframe.size.width +1;
stepperFrame.origin.y = frame.origin.y;
stepperFrame.size = pageNoframe.size;
page_move = [[UIStepper alloc] initWithFrame:stepperFrame];
[page_move setMinimumValue:0];
[page_move setValue:7];
page_move.maximumValue =1000;
[page_move addTarget:self action:#selector(nextOrPrevPage:forEvent:) forControlEvents:UIControlEventValueChanged];
page_no_view = [[UITextField alloc] initWithFrame:pageNoframe];
page_no_view.delegate = self;
page_no_view.backgroundColor = [UIColor redColor];
[self addSubview:page_no_view];
[self addSubview:page_move];
[page_move sendActionsForControlEvents:UIControlEventValueChanged];
[page_move setEnabled:YES];
}
return self;
}
-(void) nextOrPrevPage:(id) sender forEvent:(UIControlEvents) event {
//assert(sender == page_move);
NSLog(#"Event is %x", event);
page_no_view.text = [[NSNumber numberWithDouble: page_move.value] stringValue];
}
I have added this View to the navigation bar.
And I can decrement the value of the UIStepper but no increment it (the event will simply not get triggered for increment but will do so decrement).
WHY?
Using iOS 7, running on simulator.
Whenever you have a problem with a UI element not responding, the first thing you should check is whether it (or part of it) is outside the bounds of its superview (the part that's out of the bounds will not respond). An easy way to do this, is to give the superview a background color. In the init method assign a background color to self, and see what that shows you. I'm betting that you'll see that the right side of the stepper is not within its superview, so you'll need to make that view bigger, or change the stepper's position within that view.
If you make the view's frame 150x30, and change these two lines in the view's init method, I think it should work ok for a number as large as 1000:
pageNoframe.size.width = frame.size.width/4; // changed 2 to 4
stepperFrame.origin.x = pageNoframe.origin.x + pageNoframe.size.width+20; // changed 1 to 20

Resources