add something above of iPhone / iPad keyboard? - iphone

i was wondering how can i add a view on ios Keyboard ? like this :

you will want to look into the inputAccessoryView property in the UITextView or UITextField class (depending on what you are using) for a custom view above the keyboard.

If you want to only show the accessory view by itself then subclass your UIResponder view that presents the keyboard and redeclare inputView as read/write and return your accessory view in that method.
Interface
#property (atomic, retain) UIView *inputView
Implementaion
- (UIView *)inputView { return accessoryView; }
- (void)setInputView:(UIView *)aView {
if (accessoryView != aView) {
[accessoryView release];
accessoryView = [aView retain];
}
}
More information on redeclaring and adding both inputView and inputAccessoryView for any UIResponder subclass in the official Apple documentation: https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/InputViews/InputViews.html

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.

How to show UIDatePIcker over the TabBar like keyboard did

I Know there is few question on this site talk about this... but I don't find real answer that i can use...
I have a form that contain common UITextField and a UIButton that supposedly show UIDatePicker sliding from bottom when user click the button...
The main question is:
how to show UIDatePicker over the TabBar like iphone keyboard did
how make the UIDatePicker is behave like a keyboard, so when i click UITextField while
selecting date, it changed to keyboard and vice versa... like iphone contact did.
Thanks in advance
Set input View of your textfield to be a UIDatePicker object:
UITextField has following properties.
#property (readwrite, retain) UIView *inputView;
Use following code:
yourTextfield.inputView = yourDatePicker;
so instead of keyboard which is default for UITextfield, your picker will appear when textfield is tapped....
five years ago question.
1.create a subclass of the UIResponder class
2.redeclare inputview as read-write
#property (nonatomic, strong, readwrite) UIView *inputView;
3.set canBecomeFirstResponder to YES
- (BOOL)canBecomeFirstResponder {
return YES;
}
4.set inputview such as datepicker
self.inputView = self.datePicker;
5.set UIResponder to firstResponder when you want
[self becomeFirstResponder];
5.you can see datepicker show like keyboard

Issue with UISearchBar inputAccessoryView

I have created an UISearchBar and I have to insert a view in inputAccessoryView but the compiler gives me this error :
Assignment to readonly property
why this happens ? :
#property(nonatomic,retain)IBOutlet UISearchBar *searchbar;
#property (retain, nonatomic) IBOutlet UIView *keyView;
self.searchbar.inputAccessoryView = keyView;
SearchBars have a UITextView inside, you could look for it in a slightly dirty way and set the inputAccessoryView to it. I'm not sure if this will work, but it's worth a shot
UITextField *searchBarField = nil;
for (UIView *subView in searchBar.subviews) {
if ([subView conformsToProtocol:#protocol(UITextInputTraits)]) {
searchBarField = (UITextField *)subView;
searchBarField.inputAccessoryView = ...
break;
}
}
This happens, because this property is readonly, you cannot simply assign a 'UIView'. Read UISearchBar inputAccessoryView for a suggestion how to access this property. You'll have to subclass the searchbar.

How to assign multiple UIButtons to a UITextView

I want to assign two UIButtons to UITextView so that when one of the buttons is pressed the textview content should change from what it had when the previous button was pressed.
MyViewController.h:
#interface MyViewController : UIViewController
{
NSString* savedText;
}
#property(nonatomic, retain) IBOutlet UITextView* textView;
- (IBAction)buttonOnePressed:(id)sender;
- (IBAction)buttonTwoPressed:(id)sender;
#end
Connect the view controller's textView outlet to the text view in the xib file. Connect the buttons to the corresponding actions. (See Apple's Xcode tutorial if you don't know how to do this.)
MyViewController.m:
- (void)buttonOnePressed:(id)sender
{
[savedText release];
savedText = [textView.text copy];
}
- (void)buttonTwoPressed:(id)sender
{
textView.text = savedText;
}
(These aren't the complete files, of course, just the bits to make it do what you're asking.)

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.