Scrollview should start from where I left it last time - ios

I have a scrollview(timesScrollView) which is added as a subview on a view(dropDownView).The view is hidden until a particular button is pressed, when that button is pressed view will appear.
(IBAction)how_many_times_btn_click:(id)sender{
if(howMany==false){
for(UIView *view in dropDownView.subviews)
{
[view removeFromSuperview];
}
howMany=true;
duration=false;
how_many_times_btn.backgroundColor=[UIColor colorWithRed:130/255.0f green:189/255.0f blue:31/255.0f alpha:1.0f];
durationBtn.backgroundColor=[UIColor colorWithRed:62/255.0f green:67/255.0f blue:79/255.0f alpha:1.0f];
startBtn.backgroundColor=[UIColor colorWithRed:62/255.0f green:67/255.0f blue:79/255.0f alpha:1.0f];
dropDownView.hidden=NO;
dropDownView.frame=CGRectMake(0, 0, self.view.frame.size.width,70);
dropDownView.backgroundColor=[UIColor colorWithRed:37/255.0f green:42/255.0f blue:54/255.0f alpha:1.0f];
//dropDownView.backgroundColor=[UIColor whiteColor];
targetLbl=[[UILabel alloc]init];
targetLbl.frame=CGRectMake(0, 30, dropDownView.frame.size.width,30);
targetLbl.text=#"TARGET";
targetLbl.textColor=[UIColor whiteColor];
targetLbl.font=[UIFont boldSystemFontOfSize:22];
targetLbl.textAlignment=NSTextAlignmentCenter;
how_many_Lbl=[[UILabel alloc]init];
how_many_Lbl.frame=CGRectMake(0, targetLbl.frame.origin.y+targetLbl.frame.size.height, dropDownView.frame.size.width, 20);
how_many_Lbl.textAlignment=NSTextAlignmentCenter;
how_many_Lbl.text=#"HOW MANY TIMES WILL YOU DO IT?";
how_many_Lbl.textColor=[UIColor colorWithRed:65/255.0f green:71/255.0f blue:80/255.0f alpha:1.0f];
how_many_Lbl.font=[UIFont systemFontOfSize:10.0f];
hideViewBtn=[UIButton buttonWithType:UIButtonTypeCustom];
hideViewBtn.frame=CGRectMake(dropDownView.frame.size.width-30,20,20,20);
[hideViewBtn setImage:[UIImage imageNamed:#"Close Icon [ x ]"] forState:UIControlStateNormal];
[hideViewBtn addTarget:self action:#selector(hideView) forControlEvents:UIControlEventTouchUpInside];
//hideViewBtn.backgroundColor=[UIColor whiteColor];
self.timesScroll=[[LTInfiniteScrollView alloc] initWithFrame:CGRectMake(0, how_many_Lbl.frame.origin.y+how_many_Lbl.frame.size.height+16, dropDownView.frame.size.width, 102)];
//self.timesScroll.backgroundColor=[UIColor whiteColor];
self.timesScroll.verticalScroll=NO;
self.timesScroll.dataSource=self;
self.timesScroll.maxScrollDistance=5;
self.timesScroll.contentInset=UIEdgeInsetsMake(0, self.timesScroll.frame.size.width/2-31, 0,self.timesScroll.frame.size.width/2-31 );
self.timesScroll.userInteractionEnabled=YES;
self.timesScroll.exclusiveTouch=YES;
dropDownView.frame=CGRectMake(0, 0, self.view.frame.size.width,_timesScroll.frame.origin.y+_timesScroll.frame.size.height+20);
[self viewWillAppear:YES];
[dropDownView addSubview:targetLbl];
[dropDownView addSubview:how_many_Lbl];
[dropDownView addSubview:hideViewBtn];
[dropDownView addSubview:_timesScroll];
}
else
{
[self hideView];
}
}
The method above is what I am using to create view.
Now my problem is that when that particular button(how_many_times_btn) is pressed again all views are first removed then added as you can see and scrollview starts from initial position but I want it show from where I left it last time how_many_times_btn was clicked.
Hope you can understand What I am trying to say....if not I am happy to elaborate furthur.

you can get the last position by delegate methods
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
nslog(#"%f %f",scrollView.contentOffset.x,scrollView.contentOffset.y);
}
and store the x and y value and set
scrollView.contentOffset = CGPointMake(x,y);

You can save contentOffsetto one variable of CGPoint. And use this variable 's value later to scroll the UIScrollview.
Something like below line of code :
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
contentOffset = scrollView.contentOffset;
}
When button pressed write below line of code:
self.timesScroll .contentOffset = contentOffset;

I'm using LTInfiniteScrollview in which there is a method 'reloadDataWithInitialIndex'
-(void)reloadDataWithInitialIndex:(NSInteger)initialIndex
{
for (UIView *view in self.scrollView.subviews) {
[view removeFromSuperview];
}
self.views = [NSMutableDictionary dictionary];
self.visibleViewCount = [self.dataSource numberOfVisibleViews];
self.totalViewCount = [self.dataSource numberOfViews];
[self updateSize];
_currentIndex = initialIndex;
self.scrollView.contentOffset = [self contentOffsetForIndex:_currentIndex];
[self reArrangeViews];
[self updateProgress];}
This method is called in 'viewWillAppear'
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.viewSize = CGRectGetWidth(self.view.frame) / Number_of_visibleViews;
self.timesScroll.delegate=self;
[self.timesScroll reloadDataWithInitialIndex:howIndex];}
I just passed previous index value here.

Related

Custom UIView in storyboard not showing subviews

I have created a custom UIView to show an UIActivityIndicatorView and a message. Idea is to reuse this across my app for consistency. Below is the code:
#implementation CDActivityIndicator
#synthesize activityIndicator, message;
//init method called when the storyboard wants to instantiate this view
- (id) initWithCoder:(NSCoder*)coder {
if ((self = [super initWithCoder:coder])) {
activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
message = [[UILabel alloc] initWithFrame:CGRectZero];
[message setBackgroundColor:[UIColor clearColor]];
[message setTextColor:[UIColor whiteColor]];
[message setTextAlignment:NSTextAlignmentCenter];
[message setFont:[UIFont fontWithName:#"HelveticaNeue" size:15.0f]];
[self addSubview:activityIndicator];
[self addSubview:message];
//set background color
[self setBackgroundColor:[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.5]];
}
return self;
}
-(void) layoutSubviews {
[super layoutSubviews];
//position the indicator at the center of the view
[activityIndicator setCenter:[self center]];
//position the label
[message setFrame:[self frame]];
}
- (void) begin {
//make sure the current view is visible, and message is hidden
[self setHidden:NO];
[activityIndicator setHidden:NO];
[self bringSubviewToFront:activityIndicator];
[message setHidden:YES];
[self performSelectorOnMainThread:#selector(startAnimating) withObject:self waitUntilDone:YES];
}
- (void) startAnimating {
if( !activityIndicator.isAnimating ) {
[activityIndicator startAnimating];
}
}
To try this out, I added a UIView to one of my views in the storyboard and set the class for that view to CDActivityIndicator. When I call begin() from the corresponding View Controller, the CDActivityIndicator gets shown as an empty view with the expected background color. However, the activity indicator doesn't show. All methods are getting called as expected.
Any idea what I might be missing? Thanks!
You should change your subviews frame setting like this.
CGPoint point = [self.superview convertPoint:self.center toView:self];
[activityIndicator setCenter:point];
[message setFrame:self.bounds];
The frame defines the origin and dimensions of the view in the coordinate system of its superview. Every UIView has its own coordinate system. You should take this into account.

UIButtons Won't disspear after scene transition

Hey so I have created two buttons that when pressed transition the current scene to either the next scene or the main menu and they work but neither button disappears after it has been pressed. They both carry over onto the next scene which I don't want. I've tried hiding the buttons and removing them from the superView but neither worked. Heres what the code looks like for what happens when it is pressed.
-(IBAction)buttonPressed:(UIButton *)sender
{
if ([sender isEqual:self.continueButton]) {
SKTransition* reveal = [SKTransition doorsCloseVerticalWithDuration:0.5];
SKScene* transition2Scene = [[Transition2Scene alloc] initWithSize:self.size];
[self.view presentScene:transition2Scene transition: reveal];
[self.continueButton removeFromSuperview];
self.continueButton.hidden = YES;
self.continueButton.enabled = NO;
}
else {
SKTransition* doors = [SKTransition doorsCloseVerticalWithDuration:0.5];
SKScene* spriteMyScene = [[SpriteMyScene alloc] initWithSize:self.size];
[self.view presentScene:spriteMyScene transition: doors];
self.menuButton.hidden = YES;
self.menuButton.enabled = NO;
[self.menuButton removeFromSuperview];
}
}
And heres what the coding of the buttons themselves looks like.
self.continueButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
self.continueButton.frame = CGRectMake(self.frame.size.width/3, self.frame.size.height * 0.5, 120, 70);
[self.continueButton setTitle:#"Continue" forState:UIControlStateNormal];
[self.continueButton addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.continueButton];
self.menuButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
self.menuButton.frame = CGRectMake(self.frame.size.width/3, self.frame.size.height * 0.6, 120, 70);
[self.menuButton setTitle:#"Main Menu" forState:UIControlStateNormal];
[self.menuButton addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.menuButton];
I've looked around for answers and tried some things but they didn't work cause the issue I'm having isn't quite the same so any help would be greatly appreciated thanks!
The SKScene and its contents are remove from the view when transitioning to a new scene. Views, such as your buttons, are not removed. You will need to manually remove them. Here's an example...
- (IBAction) buttonPressed:(UIButton *)sender
{
[self.continueButton removeFromSuperview];
[self.menuButton removeFromSuperview];
// Find and remove all UIButtons in your view
for (UIView *view in self.view.subviews) {
if ([view isKindOfClass:[UIButton class]]) {
NSLog(#"%#", view);
[view removeFromSuperview];
}
}
// Verify that the UIButtons were removed
for (UIView *view in self.view.subviews) {
if ([view isKindOfClass:[UIButton class]]) {
NSLog(#"this shouldn't happen: %#", view);
}
}
// The rest of your code
Alternatively, you can create buttons using SKSpriteNode and add them to your scene. Here's an example...
Setting up buttons in SKScene

Custom UISearchBar wrong tint under UINavigationBar

I can't get my head around this issue: I have a UISearchBar subclass that I'm using with a UISeachDisplayControlller in a UITableViewController that adds a button on the left side and makes the UISearchTextField smaller so it can fit both views.
I set the frames manually in layoutSubviews even tough I'm using AutoLayout across the project.
The code looks something like this:
UIView *searchBarView = [self.subviews objectAtIndex:0];
[searchBarView addSubview:_annotationsButton];
for (UIView *subview in searchBarView.subviews) {
if ([subview isKindOfClass:[UITextField class]]) {
// Change the border color of the UISearchTextField
[subview.layer setBorderWidth:1.0];
[subview.layer setBorderColor:[UIColor colorFromHexString:#"#77848D"].CGColor];
[subview.layer setCornerRadius:2.0];
}
}
[self setBackgroundImage:[UIImage imageWithColor:[UIColor whiteColor]]];
self.separator = [[UIView alloc] initWithFrame:CGRectMake(0, self.bounds.size.height-1, self.bounds.size.width, 1)];
[self.separator setBackgroundColor:[UIColor colorFromHexString:#"#d6d0cc"]];
[searchBarView addSubview:self.separator];
The strange result looks like this:
As you can see, the bar is grayed out.
The layoutSubviews method is the following:
- (void)layoutSubviews{
[super layoutSubviews];
UIView *searchBarView = [self.subviews objectAtIndex:0];
for (UIView *subview in searchBarView.subviews) {
if ([subview isKindOfClass:[UITextField class]]) {
CGRect textFieldFrame = [subview frame];
if (!subview.isFirstResponder) {
self.originalFrame = textFieldFrame;
CGRect newTextFieldRect = CGRectMake(self.originalFrame.origin.x + self.originalFrame.size.width /2,
self.originalFrame.origin.y,
self.originalFrame.size.width /2 - kPadding,
self.originalFrame.size.height);
[subview setFrame:newTextFieldRect];
CGRect annotationsButtonFrame = CGRectMake(kPadding,
self.originalFrame.origin.y,
self.originalFrame.size.width /2 - kPadding,
self.originalFrame.size.height);
[self.annotationsButton setFrame:annotationsButtonFrame];
[self.annotationsButton setHidden:NO];
}
else {
[self.annotationsButton setHidden:YES];
}
}
}
[self.separator setFrame:CGRectMake(0, self.bounds.size.height-1, self.bounds.size.width, 1)];
}
In this method, I just adjust the frames of the UISearchBarTextField and _annotationsButton so they do not overlap.
Whenever the background is set with an image this happens.
I managed to set the bar translucent and with this line:
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
self.searchBarStyle = UISearchBarStyleMinimal;
}
I fixed my issue.

iCarousel is been shown up in previous page when clicked the back button

When i press the back button. the iCarousel is still shows up for 1 second.why is this happening and how to stop this.I have used storyboard to create a iCarosel view..
- (void)viewDidUnload
{
[super viewDidUnload];
self.carousel = nil;
}
- (void)dealloc
{
carousel.delegate = nil;
carousel.dataSource = nil;
}
- (NSUInteger)numberOfItemsInCarousel:(iCarousel *)carousel
{
return [idOfAllWords count];
}
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view
{
UILabel *label = nil;
//create new view if no view is available for recycling
if (view == nil)
{
view = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 250.0f, 250.0f)];
((UIImageView *)view).image = [UIImage imageNamed:#"page.png"];
view.contentMode = UIViewContentModeCenter;
label = [[UILabel alloc] initWithFrame:view.bounds];
label.backgroundColor = [UIColor clearColor];
label.textAlignment = NSTextAlignmentCenter;
label.font = [label.font fontWithSize:50];
label.tag = 1;
[view addSubview:label];
}
else
{
label = (UILabel *)[view viewWithTag:1];
}
Words *word=nil;
word=idOfAllWords[index];
label.text =word.Name;
return view;
}
Hiding and unhiding is not the solution. What you need is just one line:
yourCarousel.clipsToBounds = YES;
I actually tried to reproduce your problem and did see that the carousel view stays for a second when 'pop' or back button press happens. This particularly happens when you the carousel is swiped and then the back button pressed. As a workaround, I was able to fix it by setting the iCarousel hidden in the viewWillDisappear method.
- (void)viewWillDisappear:(BOOL)animated
{
[YOUR_CAROUSEL_NAME setHidden:YES]; //This sets the carousel to be hidden when you press Back button
}
If this looks to be hidden suddenly, you can perhaps try setting the alpha to 0.0 inside an animation block. Something like this:
- (void)viewWillDisappear:(BOOL)animated
{
//[YOUR_CAROUSEL_NAME setHidden:YES];
[UIView animateWithDuration:0.2f animations:^{
[YOUR_CAROUSEL_NAME setAlpha:0.0f]; //This makes the carousel hide smoothly
}];
}
Hope this helps!

UIButton addTarget does not in invoke selector

Let me first state, that this is not a matter of getting my selector name right, nor setting up the button target in loadView, nor any other suggestion I've seen in the last 4 hours of browsing. I should also explain I am not using nibs, nor IB.
These buttons have been working for the bulk of development.
Then poof! It's not just the buttons. My table views do not scroll. Pressing the cells in the table views do not invoke the actions that I had setup.
It seems I've broken the responder chain entirely; or something to that effect.
To try and narrow down the source of the problem a created a window-based project; stripped out everything that xCode generates; deleted the nib; and copied in several methods from my original app delegate and my rootViewController.
It's the RVT that contains the subView that contains the buttons. Fairly straight forward. Same effect. I've literally stripped out all functional code but the following source in appDelegate.m:
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[UIApplication sharedApplication] setDelegate:self];
if(window == nil)
window = [[UIWindow alloc] init];
window.autoresizesSubviews = YES;
if(controller == nil)
controller = [[Controller alloc] init];
window.rootViewController = controller;
[window makeKeyAndVisible];
return YES;
}
-(void)dealloc {
[window release];
[controller release];
[super dealloc];
}
And in Controller:
- (void)buttonResponse {
NSLog(#"Button touched up inside!!!!!");
}
- (void)loadView {
[super loadView];
//test
button = [UIButton buttonWithType:UIButtonTypeCustom];
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"Button" ofType:#"png"];
UIImage *image = [UIImage imageWithContentsOfFile:filePath];
CGSize imageSize = [image size];
CGRect buttonFrame = CGRectMake(0,0,imageSize.width + 100, BUTTONBAR_H + 100);
button.frame = buttonFrame;
[button setImage:image forState:UIControlStateNormal];
button.backgroundColor = [UIColor blueColor];
[button setTitle:#"" forState:UIControlStateNormal];
button.userInteractionEnabled = YES;
[button addTarget:self action:#selector(buttonResponse) forControlEvents: UIControlEventTouchUpInside];
UIView *view = self.view;
CGRect viewFrame = view.frame; //self.view is valid and takes up available screen
[self.view addSubview:button];
[self.view bringSubviewToFront:button];
//end test
[self.view setNeedsDisplay];
}
- (void)dealloc {
[button release];
[super dealloc];
}
I know it's gotta be something really simple. But I can't see it. I would prefer to leave my hair in place. I'm wondering if that's going to happen as I continue to learn the quirks.
Does loadView ever get called? Put a NSLog (or a breakpoint) in loadView just as a sanity check.
Also, from UIViewController Documentation:
If you override this method (loadView) in order to create your views manually,
you should do so and assign the root view of your hierarchy to the
view property. (The views you create should be unique
instances and should not be shared with any other view controller
object.) Your custom implementation of this method should not call super.
If you want to perform any additional initialization of your views, do
so in the viewDidLoad method. In iOS 3.0 and later, you
should also override the viewDidUnload method to release any
references to the view or its contents.
Try putting all the button code in viewDidLoad:
- (void)buttonResponse:(id)sender {
NSLog(#"Button touched up inside!!!!!");
}
- (void)loadView {
// Dont call super (according to the UIViewController docs)
// [super loadView];
// self.view = ... however your setting up self.view
// self.view.frame = CGRectMake....
// self.view.etc...
[self.view setNeedsDisplay];
}
- (void)viewDidLoad {
[super viewDidLoad];
button = [UIButton buttonWithType:UIButtonTypeCustom];
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"Button" ofType:#"png"];
UIImage *image = [UIImage imageWithContentsOfFile:filePath];
CGSize imageSize = [image size];
CGRect buttonFrame = CGRectMake(0,0,imageSize.width + 100, BUTTONBAR_H + 100);
button.frame = buttonFrame;
[button setImage:image forState:UIControlStateNormal];
button.backgroundColor = [UIColor blueColor];
[button setTitle:#"" forState:UIControlStateNormal];
button.userInteractionEnabled = YES;
[button addTarget:self action:#selector(buttonResponse:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
[self.view bringSubviewToFront:button];
}
- (void)dealloc {
[button release];
[super dealloc];
}

Resources