UITextView Inside UIScrollView Scrolling Parent as Text is Entered - iphone

I have a UIScrollView that contains a UITextView. As text is entered into the UITextView the UIScrollView will scroll to ensure that the text is entirely visible in the content frame. I don't want this.
I've disabled scrolling on the UIScrollView, however this has no effect. Anyone know how to stop this? A sample project can be found here: http://cl.ly/1P1u3y302r3q1f1C063K.
Thanks!

I had similar issues with UITextView. It seems scrollEnabled property does not cancel autoscrolling. I have solved it by overriding setContentOffset: method.
The following preventScrolling flag might help:
#interface MyScrollView : UIScrollView
#property (nonatomic, assign) BOOL preventScrolling;
#end
#implementation MyScrollView
#synthesize preventScrolling;
-(void) setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated
{
if(!self.preventScrolling) {
[super setContentOffset:contentOffset animated:animated];
}
}
#end

you have set the wrong contentSize: of scroll view....
always set the content size according to content inside scroll view, if content height and width is greater than scroll view height and width then only increase the content size else put it the same as its width and height of scroll view
[self.mainScrollView setContentSize:CGSizeMake(4096, 4096)];
instead of it put this contentsize:
[self.mainScrollView setContentSize:CGSizeMake(mainScrollView.frame.size.width, mainScrollView.frame.size.height)];
may this will help you

Related

iOS iPad App: Delegates not called for ViewController with two UIScrollViews and a UIPageControl (delegate functions for paging NOT CALLED)

For my iPad App, I have a main ViewController which contains two UIScrollviews and a UIPageControl.
The Problem is that the delegates for the paging are not getting called.
Here is the layout:
Selecting a button in the lower thumbScrollView needs to update the image in the mainScrollView (this works) Swiping the thumbScrollView or picking a dot on the pageControl needs to "page" the thumbScrollView to show the next previous set of buttons. The swiping does not work because the delegate functions are just not getting called.
I declare the scrollviews and pagecontrol as follows in my VC
#property (strong, nonatomic) IBOutlet UIScrollView *mainScrollView;
#property (strong, nonatomic) IBOutlet UIScrollView *thumbScrollView;
#property (strong, nonatomic) IBOutlet UIPageControl *pageControl;
The ViewController implements UIScrollViewDelegate
#interface MyViewController : UIViewController<UIScrollViewDelegate>
And I implement the following UIScrollViewDelegate delegate functions in my VC's .m file.
- (void)scrollViewDidScroll:(UIScrollView *)sender;
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView;
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;
The view appears but when I swipe across the buttons I do not see the delegate functions above getting called.
I have not found a solution to this in StackOverflow although I have factored in advise from other related posts for other aspects of this (ex. the logic to distinguish which scrollview has initiated the action etc)
ADDING DETAILED CODE HERE (as requested by #HeWas)
This is the header file for the Main View Controller that controls the two scrollviews and pagecontrol (RELEVANT EXCERPTS - TELL ME IF YOU NEED MORE)
// ImageBrowseViewController.h
// (NOTE - In Interface Builder I have added a tag attribute of 0 to mainScrollView
// and 1 to thumbScrollView, to enable me to distinguish which scrollView the delegate
// needs to respond to)
#define TAG_MAIN_SCROLLVIEW 0
#define TAG_THUMB_SCROLLVIEW 1
#interface ImageBrowseViewController : UIViewController<UIScrollViewDelegate>
{
UIButton* currentlySelectedButton;
UIScrollView *mainScrollView;
UIScrollView *thumbScrollView;
UIPageControl* pageControl;
BOOL pageControlBeingUsed;
}
#property (strong, nonatomic) IBOutlet UIScrollView *mainScrollView;
// … connected as outlet in IB to mainScrollView
#property (strong, nonatomic) IBOutlet UIScrollView * thumbScrollView;
// … connected as outlet in IB to thumbScrollView
#property (strong, nonatomic) IBOutlet UIPageControl *pageControl;
// … connected as outlet in IB to pageControl
…
-(IBAction)changePage; //Touch up Inside IBAction connected to pageControl
…
#end
This is the implementation file for the Main View Controller that controls the two scrollviews and pagecontrol (RELEVANT EXCERPTS - TELL ME IF YOU NEED MORE)
//
// ImageBrowseViewController.m
//
…
#synthesize mainScrollView;
#synthesize thumbScrollView;
#synthesize pageControl;
// UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)sender {
if ( [sender tag] == TAG_THUMB_SCROLLVIEW ) {
// This is the thumbScrollview
// Update the page when more than 50% of the previous/next page is visible
CGFloat pageWidth = self.thumbScrollView.frame.size.width;
int page =
floor((self.thumbScrollView.contentOffset.x - pageWidth / 2) / pageWidth)
+ 1;
self.pageControl.currentPage = page;
}
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
pageControlBeingUsed = NO;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
pageControlBeingUsed = NO;
}
- (IBAction)changePage {
// Update the scroll view to the appropriate page
CGRect frame;
//frame.origin.x = self.scrollView.frame.size.width * self.pageControl.currentPage;
frame.origin.x = self.thumbScrollView.frame.size.width * self.pageControl.currentPage;
frame.origin.y = 0;
frame.size = self.thumbScrollView.frame.size;
[self.thumbScrollView scrollRectToVisible:frame animated:YES];
// Keep track of when scrolls happen in response to the page control
// value changing. If we don't do this, a noticeable "flashing" occurs
// as the the scroll delegate will temporarily switch back the page
// number.
pageControlBeingUsed = YES;
}
You code all looks 100% (aside from this typo: #synthesize floorplanThumbScrollView;, but that isn't your problem).
I am sure that the answer is that you have not correctly wired your scrollview DELEGATES in IB.
This is the clue:
"Yes I have set all three in Interface Builder. So mainScrollView, thumbScrollView, and pageControl are wired in IB to the above declarations in the VC's .h file."
You need 2 connections between your ViewController and your scrollViews.
(1) ctrl-drag FROM viewController TO scrollView, connect to IBOutlet property.
This is what you have done.
(2) ctrl-drag FROM scrollView TO viewController, connect to delegate.
I do not think you have done this.
Explanation of step 2
UIScrollView has a built-in property called 'delegate'. The scrollView uses this property to send messages to it's delegate. You set this delegate in interface builder (step 2) or you can do it in code. For example in your viewController you could do this:
[myScrollView setDelegate:self];
which would set the viewController as the delegate for myScrollView. If you do it by linking in Interface Builder you don't need this code (and IB doesn't create any).
Either way what this actually does is set scrollView's delegate iVar to a pointer to the viewController. The great thing about using delegates like this is that the delegator (UIScrollView) doesn't have to know anything about the delegatee (in this case your UIViewController). This allows us to reuse UIScrollView so long as we observe it's delegate protocol.
Whenever the scrollView needs to notify it's delegate, internally it sends a message like this..
[self.delegate scrollViewDidScroll:self];
(you don't see that, it's in the scrollView's implementation).
The object that you have set as the delegate to scrollView needs to implement all of the required methods that the scrollView's delegate protocol declares, and can choose to implement any of the optional delegate methods. Here is the protocol
To work out which methods are required, read the UIScrollView class reference, which tells you this:
The UIScrollView class can have a delegate that must adopt the UIScrollViewDelegate protocol. For zooming and panning to work, the delegate must implement both viewForZoomingInScrollView: and scrollViewDidEndZooming:withView:atScale:; in addition, the maximum (maximumZoomScale) and minimum (minimumZoomScale) zoom scale must be different.
Everything else in the protocol is optional.
This delegate pattern is one you can easily implement yourself for your own object reuse, and is one of the most common ways of passing messages between decoupled objects in objective-C.

UIScrollView stops working when label text in UIScrollView is changed

I have had this problem for a long time now, I hope stackoverflow can help!
THE PROBLEM IS
When I enter "Alan Shearer" into the EnterNameText (UI TEXTFIELD) the label changes text, however the ScrollView no longer scrolls to the set content size, it will scroll a little bit, but no were near the set content size, in this case 2000px in height.
details
1) Xcode 4.5.1
2) IOS 6
In my .xib file ( tinypic.com/view.php?pic=2h4yx3o&s=6 ) I have a UIScrollView (320 pixels in width, and 490 pixels in height)
The UIScrollView contains labels that are all connected to view controller.h.
The Label (all labels are set in the same way) :
#property (strong, nonatomic) IBOutlet UILabel *AlanShearerLabel;
my UIScrollView in ViewController.h looks like this:
#property (strong, nonatomic) IBOutlet UIScrollView *scrollview;
UIScrollView in ViewController.m
- (void)viewDidAppear:(BOOL)animated{[super viewDidAppear:animated]; self.scrollview.contentSize=CGSizeMake(320.0, 2000.0); }
An IBAction called - (IBAction)CheckButton:(id)sender
The action when CheckButton is clicked:
//string 0
NSString *string0 = _EnterNameText.text;
//Alan Shearer
NSString *string1 =#"Alan Shearer";
NSString *string2 =#"Rank 1) Alan Shearer 260 Goals";
NSString *stringshearer =#"Shearer";
//Alan Shearer IF
if([string0 isEqualToString:string1]||
[string0 isEqualToString:stringshearer])
{_AlanShearerLabel.text = string2;
_AlanShearerLabel.textColor = [UIColor greenColor];
_EnterNameText.text=#"";
}
To solve this issue you must be sure to define all the things inside the scrollview before you link the scrollview to the .h file. For example if you have 20 labels in a scrollview, be sure that the 20 labels have been connected to the .h file, set the right size, put in the right place. Only then do you connect your scrollview to the .h file and place the scrollview code in viewDidAppear rather then viewdidload.

Fixed footer of a UItableview. always at the footer position

Im trying to have a footer Fixed at the bottom of a uitableview. it will always be at the bottom, not scrollable with the table cells. It also cant cut out and cells like cover the last cell of a uitable view so one cell will be hidden. I have the following header file:
//fooer contains a number_of_total_clicks label, an a proceedtopayment button.
#interface checkout : UITableViewController
#property (retain, nonatomic) IBOutlet UILabel *number_of_total_clicks;
- (IBAction)proceedtonextview:(id)sender;
#property (retain, nonatomic) IBOutlet UIView *footer; //?
#property (strong, nonatomic) NSMutableDictionary *items_clicked;
#end
and in my .m file
- (void)viewDidLoad
{
[super viewDidLoad];
//self.tableView.tableFooterView= footer; ??
number_of_total_clicks.text=#"0";
}
//void or IBAction?V
- (void)add_item_to_array_of_clicks_which_will_increment_number_of_total_clicks_value:(id)sender{
number_of_total_clicks.text=[NSString stringWithFormat:#"$%.2f",[sender doubleValue]*5];
[self.tableView reloadData];
}
What happens is I get a footer the is basically attached to the last cell of the table so if the table has only 3 cells, the "footer" with the number_of_total_clicks will be attached as a 4th cell. if there are 45 cells, he footer will be he 46th cell only accesible once I scroll all the way down. I want it o be fixed a the bottom. Thanks
In your -loadView method try manually creating your view using [UIScreen mainScreen]. applicationFrame as the frame. Note that you should use a UIView, not a table view.
This view will fill the whole screen (except for tab and navbars, when using them).
You can then manually add a UITableView as the VC's tableView, but don't make it fill the whole view. Leave some space at the bottom, just as much to fit your 'table footer' in. Remember to set the tableView to have a flexible width as well as a flexible height.
Now for the 'table footer' just add it as a subview to self.view (not self.tableView) and place it at the very bottom of self.view. This view should have a flexible width and a flexible top margin.
I hope this fits your needs.

Resizing UITableView When Displaying AdWhirl Ads Across Multiple Views

I am trying to integrate AdWhirl into my iPhone app using an AppDelegate singleton so I can use the same AdWhirl instance across multiple views, but cannot figure out how to resize the tables in those views. The code I am using is:
in ...AppDelegate.h:
#import "AdWhirlView.h"
#import "AdWhirlDelegateProtocol.h"
#interface ...AppDelegate : NSObject <UIApplicationDelegate, AdWhirlDelegate>
AdWhirlView *awView;
...
#property (nonatomic, retain) AdWhirlView *awView;
in ...AppDelegate.m didFinishLaunchingWithOptions:
awView = [AdWhirlView requestAdWhirlViewWithDelegate:self];
also in ...AppDelegate.m I add the required delegate methods
(NSString *)adWhirlApplicationKey...
(UIViewController *)viewControllerForPresentingModalView...
This code allows me to display the same Ad across multiple views but I cannot figure out how to resize a UITableView to change its height to be shorter if an Ad is displaying, so that the UITableView either displays full height if there is no Ad, or is resized if there is an Ad at the bottom of the screen. I have the UITableView as a subview of a UIViewController called myMainView.
I tried changing the autosize properties in the Nib file for the UITableView to have a variable spacer at the bottom, and am adding the AdWhirl instance into the view with this code:
...AppDelegate * myDelegate = (...AppDelegate *)[[UIApplication sharedApplication] delegate];
[myDelegate.awView setFrame:CGRectMake(0, 480-20-44-50, 320, 50)];
[self.myMainView addSubview: myDelegate.awView];
This displays the Ad at the correct location at the bottom of the screen but the UITableView is not resizing. How should I be doing this?
I think you have to create a UIView with an embedded UITableView. I've tried to do something similar and this was the only way I could get it to work. A top-level UITableView is auto-resized to take up the entire screen.
Just expanding on that, you probably want to declare something in your header like so:
#interface ExampleClass:UIViewController {
UITableView *tableView;
}
#property (nonatomic,retain) IBOutlet UITableView *tableView;
Then in your actual implementation, you can resize that declared tablview whenever you need to by doing:
CGRect tableFrame = tableView.frame;
//Decrease the height of table by height of ad banner
tableFrame.size.height = tableView.frame.size.height - adBannerView.frame.size.height;
tableView.frame = tableFrame;

How to position your custom UIView control derived from UITextField

I have extended UITextField so that I can use my custom myInputView. But I am having trouble positioning the myInputView to a desire location. Doesn't matter what i do to set the CGRect frame of myInputView it will position the height be at the bottom of the screen.
See Screenshot:
As you can see in the picture the reversed number pad is my custom inputView, but I want to be able to position it towards the middle of the screen.
MyTextField.h
#interface MyTextField : UITextField {
UIView *myInputView;
}
#property (nonatomic, retain) IBOutlet UIView *myInputView;
#end
MyTextField.m
#implementation MyTextField
#synthesize myInputView;
- (UIView *)inputView {
NSLog(#"Return inputView");
CGRect frame = CGRectMake(0, 200, 320, 215);
[myInputView setFrame:frame];
return myInputView;
}
- (void)dealloc {
[super dealloc];
[myInputView release];
}
#end
You might want to consider NOT implementing this in terms of an input view. Setting the input view lets the system treat it like it treats the keyboard. You DON'T get to set the frame, only the height. I would recommend getting rid of the UITextField, and replacing it with a UILabel with a UIButton over it. Add your custom input view to the main view, and position it offscreen. When the button is pressed, animate your custom input view back on screen. When the user makes inputs, just update the label. Don't worry about first responder or the UITextField.inputView at all.