I have a class which inherits from UIView and conforms to UIKeyInput
*.h*
#interface UIKeyInputExampleView : UIView <UIKeyInput>{
NSMutableString *textStore;
}
#property (nonatomic, retain) NSMutableString *textStore;
#end
.m
#implementation UIKeyInputExampleView
#synthesize textStore;
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
// Initialization code
self.textStore = [NSMutableString string];
[self.textStore appendString:#"Touch screen to edit."];
self.backgroundColor = [UIColor whiteColor];
}
return self;
}
- (void)dealloc {
[textStore dealloc];
[super dealloc];
}
#pragma mark -
#pragma mark Respond to touch and become first responder.
- (BOOL)canBecomeFirstResponder { return YES; }
-(void) touchesBegan: (NSSet *) touches withEvent: (UIEvent *) event {
[self becomeFirstResponder];
}
#pragma mark -
#pragma mark Drawing
- (void)drawRect:(CGRect)rect {
CGRect rectForText = CGRectInset(rect, 20.0, 20.0);
UIRectFrame(rect);
[self.textStore drawInRect:rectForText withFont:[UIFont fontWithName:#"Helvetica" size:24.0f]];
}
#pragma mark -
#pragma mark UIKeyInput Protocol Methods
- (BOOL)hasText {
if (textStore.length > 0) {
return YES;
}
return NO;
}
- (void)insertText:(NSString *)theText {
NSLog(#"Text have just enter:%# length=%d ascii=%d",theText,theText.length,[theText characterAtIndex:0]);
if ([theText isEqualToString:#"\n"]) {
NSLog(#"Enter have just pressed!");
[self resignFirstResponder];
}
self.textStore = (NSMutableString*)theText;
[self setNeedsDisplay];
}
- (void)deleteBackward {
self.textStore = (NSMutableString*)#"delete";
[self setNeedsDisplay];
}
#end
When I use the English or Vietnamese keyboard, everything is right. but when I use Japanese keyboard, no event is called, no exception is thrown.
I think I have not conformed some protocol
Can you help me?
It took some time, but finally it works.
1. For single character - I still use UIKeyInput protocol.
2. For east-asian languages I use NSString property intlInput to get all input characters. Below are two methods of UITextInput protocol that allow to do this.
- (void)setMarkedText:(NSString *)markedText selectedRange:(NSRange)selectedRange {
self.intlInput = markedText;
}
- (void) unmarkText {
if (!self.intlInput) return;
for (int i=0;i<self.intlInput.length;i++) {
[self sendChar:[self.intlInput characterAtIndex:i]];
}
self.intlInput = nil;
}
sendChar - is any method that called to take all characters of combined input. You can post notification when text is unmarked (some combination is chosen).
i have solved the problem , this example show how convert chinese input to insertText in ios.
#ifndef UIKeyInputExampleView_h
#define UIKeyInputExampleView_h
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#interface UIKeyInputExampleView : UIView <UIKeyInput,UITextInput>{
NSMutableString *textStore;
}
#property (nonatomic, retain) NSString *textStore;
#end
#endif /* UIKeyInputExampleView_h */
//
// UIKeyInputExampleView.m
// CustomInput
//
// Created by Gust on 2018/11/27.
// Copyright © 2018 Gust. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "UIKeyInputExampleView.h"
#implementation UIKeyInputExampleView
#synthesize textStore;
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
// Initialization code
self.textStore = [NSMutableString string];
//[self.textStore appendString:#"Touch screen to edit."];
//[self.textStore
self.backgroundColor = [UIColor whiteColor];
}
return self;
}
- (void)dealloc {
//[textStore dealloc];
//[super dealloc];
}
#pragma mark -
#pragma mark Respond to touch and become first responder.
- (BOOL)canBecomeFirstResponder { return YES; }
-(void) touchesBegan: (NSSet *) touches withEvent: (UIEvent *) event {
[self becomeFirstResponder];
}
#pragma mark -
#pragma mark Drawing
- (void)drawRect:(CGRect)rect {
CGRect rectForText = CGRectInset(rect, 20.0, 20.0);
UIRectFrame(rect);
[self.textStore drawInRect:rectForText withFont:[UIFont fontWithName:#"Helvetica" size:24.0f]];
}
#pragma mark -
#pragma mark UIKeyInput Protocol Methods
- (BOOL)hasText {
if (textStore.length > 0) {
return YES;
}
return NO;
}
- (void)insertText:(NSString *)theText {
NSLog(#"Text have just enter:%# length=%d ascii=%d",theText,theText.length,[theText characterAtIndex:0]);
if ([theText isEqualToString:#"\n"]) {
NSLog(#"Enter have just pressed!");
[self resignFirstResponder];
}
self.textStore = (NSMutableString*)theText;
[self setNeedsDisplay];
}
- (void)deleteBackward {
self.textStore = (NSMutableString*)#"delete";
[self setNeedsDisplay];
}
#synthesize beginningOfDocument;
#synthesize endOfDocument;
#synthesize inputDelegate;
#synthesize markedTextRange;
#synthesize markedTextStyle;
#synthesize selectedTextRange;
#synthesize tokenizer;
- (UITextWritingDirection)baseWritingDirectionForPosition:(nonnull UITextPosition *)position inDirection:(UITextStorageDirection)direction {
return UITextWritingDirectionLeftToRight;
}
- (CGRect)caretRectForPosition:(nonnull UITextPosition *)position {
return CGRectMake(0, 0, 10, 30);
}
- (nullable UITextRange *)characterRangeAtPoint:(CGPoint)point {
return nil;
}
- (nullable UITextRange *)characterRangeByExtendingPosition:(nonnull UITextPosition *)position inDirection:(UITextLayoutDirection)direction {
return nil;
}
- (nullable UITextPosition *)closestPositionToPoint:(CGPoint)point {
return nil;
}
- (nullable UITextPosition *)closestPositionToPoint:(CGPoint)point withinRange:(nonnull UITextRange *)range {
return nil;
}
- (NSComparisonResult)comparePosition:(nonnull UITextPosition *)position toPosition:(nonnull UITextPosition *)other {
return NSOrderedSame;
}
- (CGRect)firstRectForRange:(nonnull UITextRange *)range {
return [self bounds];
}
- (NSInteger)offsetFromPosition:(nonnull UITextPosition *)from toPosition:(nonnull UITextPosition *)toPosition {
return NSIntegerMax;
}
- (nullable UITextPosition *)positionFromPosition:(nonnull UITextPosition *)position inDirection:(UITextLayoutDirection)direction offset:(NSInteger)offset {
return nil;
}
- (nullable UITextPosition *)positionFromPosition:(nonnull UITextPosition *)position offset:(NSInteger)offset {
return nil;
}
- (nullable UITextPosition *)positionWithinRange:(nonnull UITextRange *)range farthestInDirection:(UITextLayoutDirection)direction {
return nil;
}
- (void)replaceRange:(nonnull UITextRange *)range withText:(nonnull NSString *)text {
//NSLog(#"replaceRange %#",text);
}
- (nonnull NSArray<UITextSelectionRect *> *)selectionRectsForRange:(nonnull UITextRange *)range {
NSArray *arr = NULL;
arr = #[];
return arr;
}
- (void)setBaseWritingDirection:(UITextWritingDirection)writingDirection forRange:(nonnull UITextRange *)range {
//self.textStore = markedText;
}
- (void)setMarkedText:(nullable NSString *)markedText selectedRange:(NSRange)selectedRange {
//NSLog(#"setMarkedText %#",markedText);
self.textStore=markedText;
}
- (nullable NSString *)textInRange:(nonnull UITextRange *)range {
//NSLog(#"textInRange ");
return nil;
}
- (nullable UITextRange *)textRangeFromPosition:(nonnull UITextPosition *)fromPosition toPosition:(nonnull UITextPosition *)toPosition {
return nil;
}
- (void)unmarkText {
if (!self.textStore) return;
[self insertText:textStore];
self.textStore = nil;
//NSLog(#"unmarkText ");
}
- (void)encodeWithCoder:(nonnull NSCoder *)aCoder {
}
+ (nonnull instancetype)appearance {
return nil;
}
+ (nonnull instancetype)appearanceForTraitCollection:(nonnull UITraitCollection *)trait {
return nil;
}
+ (nonnull instancetype)appearanceForTraitCollection:(nonnull UITraitCollection *)trait whenContainedIn:(nullable Class<UIAppearanceContainer>)ContainerClass, ... {
return nil;
}
+ (nonnull instancetype)appearanceForTraitCollection:(nonnull UITraitCollection *)trait whenContainedInInstancesOfClasses:(nonnull NSArray<Class<UIAppearanceContainer>> *)containerTypes {
return nil;
}
+ (nonnull instancetype)appearanceWhenContainedIn:(nullable Class<UIAppearanceContainer>)ContainerClass, ... {
return nil;
}
+ (nonnull instancetype)appearanceWhenContainedInInstancesOfClasses:(nonnull NSArray<Class<UIAppearanceContainer>> *)containerTypes {
return nil;
}
- (void)traitCollectionDidChange:(nullable UITraitCollection *)previousTraitCollection {
}
- (CGPoint)convertPoint:(CGPoint)point fromCoordinateSpace:(nonnull id<UICoordinateSpace>)coordinateSpace {
return CGPointMake(0, 0);
}
- (CGPoint)convertPoint:(CGPoint)point toCoordinateSpace:(nonnull id<UICoordinateSpace>)coordinateSpace {
return CGPointMake(0, 0);
}
- (CGRect)convertRect:(CGRect)rect fromCoordinateSpace:(nonnull id<UICoordinateSpace>)coordinateSpace {
return CGRectMake(0, 0,1,1);
}
- (CGRect)convertRect:(CGRect)rect toCoordinateSpace:(nonnull id<UICoordinateSpace>)coordinateSpace {
return CGRectMake(0, 0,1,1);
}
- (void)didUpdateFocusInContext:(nonnull UIFocusUpdateContext *)context withAnimationCoordinator:(nonnull UIFocusAnimationCoordinator *)coordinator {
}
- (void)setNeedsFocusUpdate {
}
- (BOOL)shouldUpdateFocusInContext:(nonnull UIFocusUpdateContext *)context {
return YES;
}
- (void)updateFocusIfNeeded {
}
- (nonnull NSArray<id<UIFocusItem>> *)focusItemsInRect:(CGRect)rect {
NSArray *arr = NULL;
arr = #[];
return arr;
}
#end
Related
enter image description here $ The data of assigned array is not showing in the pickerView. What mistake I am doing as I haven't being able to identify my mistake.
Its .m file code:
// PickerViewController.m
// dropDownButtonTry
//
#import "PickerViewController.h"
#interface PickerViewController ()
{
NSArray *genderArray;
NSArray *cityArray;
NSArray *currentArray;
UITextField *currentTextField;
}
#end
#implementation PickerViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
cityArray = [[NSArray alloc]initWithObjects:#"Delhi",#"Mumbai",#"Chennai", nil];
genderArray = [[NSArray alloc]initWithObjects:#"Male",#"Female",#"Transgender", nil];
self.pickerView.hidden = YES;
self.btnDoneOutlet.hidden = YES;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[self.view endEditing:YES];
}
//Needed to prevent keyboard from opening
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
currentTextField = textField;
if (textField == self.textFieldGenderOutlet) {
currentArray = genderArray;
}
if (textField == self.textFieldCityOutlet) {
currentArray = cityArray;
}
// do here everything you want
NSLog(#"Pressed on TextField!");
self.pickerView.hidden = NO;
self.btnDoneOutlet.hidden = NO;
[self.view endEditing:YES]; // Hide keyboard
NSLog(#"****current array**** %#",currentArray);
return NO;
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return [currentArray count];
}
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
[currentTextField setText:[currentArray objectAtIndex:row]];
}
-(NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [currentArray objectAtIndex:row];
}
- (IBAction)textFieldGenderAction:(id)sender {
self.pickerView.hidden = NO;
self.btnDoneOutlet.hidden = NO;
}
- (IBAction)btnDone:(id)sender {
self.pickerView.hidden = YES;
self.btnDoneOutlet.hidden = YES;
}
- (IBAction)textFieldCityAction:(id)sender {
}
#end
You need to reload picker view :
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
currentTextField = textField;
if (textField == self.textFieldGenderOutlet) {
currentArray = genderArray;
}
if (textField == self.textFieldCityOutlet) {
currentArray = cityArray;
}
// do here everything you want
NSLog(#"Pressed on TextField!");
self.pickerView.hidden = NO;
self.btnDoneOutlet.hidden = NO;
[self.thePicker reloadAllComponents];
[self.view endEditing:YES]; // Hide keyboard
NSLog(#"****current array**** %#",currentArray);
return NO;
}
currentArray is assigned value in textFieldShouldBeginEditing but it is not initialized anywhere in your code.
Just initialize currentArray in viewDidLoad like below:
currentArray = [NSArray new];
I've tried reading the google places API. and tried to duplicate their work. But I think I'm missing some steps here.
Here is the code for header my header file.
#class SPGooglePlacesAutocompleteQuery;
#interface GoogleMapViewViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, UISearchDisplayDelegate, UISearchBarDelegate, MKMapViewDelegate, UISearchControllerDelegate>
{
NSArray *searchResultPlaces;
SPGooglePlacesAutocompleteQuery *searchQuery;
MKPointAnnotation *selectedPlaceAnnotation;
BOOL shouldBeginEditing;
}
#property (strong, nonatomic) UISearchController *searchController;
#property (retain, nonatomic) IBOutlet MKMapView *mapView;
#end
My implementation file
#import "GoogleMapViewViewController.h"
#import "SPGooglePlacesAutocompleteQuery.h"
#import "SPGooglePlacesAutocompletePlace.h"
#interface GoogleMapViewViewController ()
#property (weak, nonatomic) IBOutlet UISearchBar *searchBar;
#end
#implementation GoogleMapViewViewController
#synthesize mapView;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
searchQuery = [[SPGooglePlacesAutocompleteQuery alloc] init];
searchQuery.radius = 100.0;
shouldBeginEditing = YES;
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.searchBar.placeholder = #"Search or Address";
self.searchBar.delegate = self;
}
- (void)viewDidUnload {
[self setMapView:nil];
[super viewDidUnload];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
#pragma mark -
#pragma mark UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [searchResultPlaces count];
}
- (SPGooglePlacesAutocompletePlace *)placeAtIndexPath:(NSIndexPath *)indexPath {
return [searchResultPlaces objectAtIndex:indexPath.row];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"SPGooglePlacesAutocompleteCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.textLabel.font = [UIFont fontWithName:#"GillSans" size:16.0];
cell.textLabel.text = [self placeAtIndexPath:indexPath].name;
return cell;
}
#pragma mark UITableViewDelegate
- (void)recenterMapToPlacemark:(CLPlacemark *)placemark {
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta = 0.02;
span.longitudeDelta = 0.02;
region.span = span;
region.center = placemark.location.coordinate;
[self.mapView setRegion:region];
}
- (void)addPlacemarkAnnotationToMap:(CLPlacemark *)placemark addressString:(NSString *)address {
[self.mapView removeAnnotation:selectedPlaceAnnotation];
selectedPlaceAnnotation = [[MKPointAnnotation alloc] init];
selectedPlaceAnnotation.coordinate = placemark.location.coordinate;
selectedPlaceAnnotation.title = address;
[self.mapView addAnnotation:selectedPlaceAnnotation];
}
- (void)dismissSearchControllerWhileStayingActive {
// Animate out the table view.
NSTimeInterval animationDuration = 0.3;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:animationDuration];
self.searchDisplayController.searchResultsTableView.alpha = 0.0;
[UIView commitAnimations];
[self.searchDisplayController.searchBar setShowsCancelButton:NO animated:YES];
[self.searchDisplayController.searchBar resignFirstResponder];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
SPGooglePlacesAutocompletePlace *place = [self placeAtIndexPath:indexPath];
[place resolveToPlacemark:^(CLPlacemark *placemark, NSString *addressString, NSError *error) {
if (error) {
SPPresentAlertViewWithErrorAndTitle(error, #"Could not map selected Place");
} else if (placemark) {
[self addPlacemarkAnnotationToMap:placemark addressString:addressString];
[self recenterMapToPlacemark:placemark];
[self dismissSearchControllerWhileStayingActive];
[self.searchDisplayController.searchResultsTableView deselectRowAtIndexPath:indexPath animated:NO];
}
}];
}
#pragma mark UISearchDisplayDelegate
- (void)handleSearchForSearchString:(NSString *)searchString {
searchQuery.location = self.mapView.userLocation.coordinate;
searchQuery.input = searchString;
[searchQuery fetchPlaces:^(NSArray *places, NSError *error) {
if (error) {
SPPresentAlertViewWithErrorAndTitle(error, #"Could not fetch Places");
} else {
searchResultPlaces = places;
[self.searchDisplayController.searchResultsTableView reloadData];
}
}];
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
[self handleSearchForSearchString:searchString];
// Return YES to cause the search result table view to be reloaded.
return YES;
}
- (BOOL)searchController:(UISearchController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
[self handleSearchForSearchString:searchString];
// Return YES to cause the search result table view to be reloaded.
return YES;
}
#pragma mark UISearchBar Delegate
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
if (![searchBar isFirstResponder]) {
// User tapped the 'clear' button.
shouldBeginEditing = NO;
[self.searchDisplayController setActive:NO];
[self.mapView removeAnnotation:selectedPlaceAnnotation];
}
}
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
if (shouldBeginEditing) {
// Animate in the table view.
NSTimeInterval animationDuration = 0.3;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:animationDuration];
self.searchDisplayController.searchResultsTableView.alpha = 1.0;
[UIView commitAnimations];
[self.searchDisplayController.searchBar setShowsCancelButton:YES animated:YES];
}
BOOL boolToReturn = shouldBeginEditing;
shouldBeginEditing = YES;
return boolToReturn;
}
#pragma mark MKMapView Delegate
- (MKAnnotationView *)mapView:(MKMapView *)mapViewIn viewForAnnotation:(id <MKAnnotation>)annotation {
if (mapViewIn != self.mapView || [annotation isKindOfClass:[MKUserLocation class]]) {
return nil;
}
static NSString *annotationIdentifier = #"SPGooglePlacesAutocompleteAnnotation";
MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[self.mapView dequeueReusableAnnotationViewWithIdentifier:annotationIdentifier];
if (!annotationView) {
annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:annotationIdentifier];
}
annotationView.animatesDrop = YES;
annotationView.canShowCallout = YES;
UIButton *detailButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[detailButton addTarget:self action:#selector(annotationDetailButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
annotationView.rightCalloutAccessoryView = detailButton;
return annotationView;
}
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views {
// Whenever we've dropped a pin on the map, immediately select it to present its callout bubble.
[self.mapView selectAnnotation:selectedPlaceAnnotation animated:YES];
}
- (void)annotationDetailButtonPressed:(id)sender {
// Detail view controller application logic here.
}
#end
I am really confused now to my implementation file as I cannot really understand what is in there TBH.plus some codes here are mostly deprecated. Someone care to give a detailed guide about this? or explain to me in layman's term. TIA.
ANSWERED!
Basically my problem was in this function given on the sample project of google places API..
BOOL SPEnsureGoogleAPIKey() {
BOOL userHasProvidedAPIKey = YES;
if (![kGoogleAPIKey isEqualToString:#"AIzaSyA2vs9pJoLrLs6XU8IRVHo7WxiuMufYXl8"]) {
userHasProvidedAPIKey = NO;
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"API Key Needed" message:#"Please replace kGoogleAPIKey with your Google API key." delegate:nil cancelButtonTitle:#"Dismiss" otherButtonTitles:nil];
[alert show];
}
return userHasProvidedAPIKey;
}
The if statement originally is incorrect that's why it always gives me the wrong value. now its working :) just added the not "!" in if
I have a view that implements UIKeyInput and overrides shouldBecomeFirstResponder to return YES. When this view is tapped, the keyboard pops up. If the user taps the dictation button, pushes done, and then tries to dismiss the keyboard, the app crashes with:
Fatal Exception: NSInternalInconsistencyException NSInternalInconsistencyException
We were never set up properly to stream in this document.
I was wondering if anyone knows a work around to fix this bug? I tried implementing UITextInput and leaving dictation related methods blank and this actually works. However, UITextInput is accessing my insertText method when the user tries to use Dictation and putting in junk. I'm not yet ready to implement dictation, so I'd actually just like to disable it for now with some sort of work around. Any input would be appreciated!
Actually, implementing UITextInput fixes the problem. When the user does a successful dictation, it will just send a space to your insertText method (not exactly sure how to get dictation to work correctly in a custom text view, right now I'm just wanting to fix this bug). Below I've listed all the methods and properties you have to use for UITextInput to save you some time:
Properties:
#property(nonatomic, readonly) UITextPosition *beginningOfDocument;
#property(nonatomic, readonly) UITextPosition *endOfDocument;
#property(nonatomic, assign) id<UITextInputDelegate> inputDelegate;
#property(nonatomic, readonly) UITextRange *markedTextRange;
#property(nonatomic, copy) NSDictionary *markedTextStyle;
#property(readwrite, copy) UITextRange *selectedTextRange;
#property(nonatomic, readonly) id<UITextInputTokenizer> tokenizer;
Methods:
- (UITextWritingDirection)baseWritingDirectionForPosition:(UITextPosition *)position inDirection:(UITextStorageDirection)direction
{
return nil;
}
- (CGRect)caretRectForPosition:(UITextPosition *)position
{
return CGRectZero;
}
- (void)unmarkText
{
}
- (UITextRange *)characterRangeAtPoint:(CGPoint)point
{
return nil;
}
- (UITextRange *)characterRangeByExtendingPosition:(UITextPosition *)position inDirection:(UITextLayoutDirection)direction
{
return nil;
}
- (UITextPosition *)closestPositionToPoint:(CGPoint)point
{
return nil;
}
- (UITextPosition *)closestPositionToPoint:(CGPoint)point withinRange:(UITextRange *)range
{
return nil;
}
- (NSComparisonResult)comparePosition:(UITextPosition *)position toPosition:(UITextPosition *)other
{
return nil;
}
- (void)dictationRecognitionFailed
{
}
- (void)dictationRecordingDidEnd
{
}
- (CGRect)firstRectForRange:(UITextRange *)range
{
return CGRectZero;
}
- (CGRect)frameForDictationResultPlaceholder:(id)placeholder
{
return CGRectZero;
}
- (void)insertDictationResult:(NSArray *)dictationResult
{
}
- (id)insertDictationResultPlaceholder
{
return nil;
}
- (NSInteger)offsetFromPosition:(UITextPosition *)fromPosition toPosition:(UITextPosition *)toPosition
{
return nil;
}
- (UITextPosition *)positionFromPosition:(UITextPosition *)position inDirection:(UITextLayoutDirection)direction offset:(NSInteger)offset
{
return nil;
}
- (UITextPosition *)positionFromPosition:(UITextPosition *)position offset:(NSInteger)offset
{
return nil;
}
- (UITextPosition *)positionWithinRange:(UITextRange *)range farthestInDirection:(UITextLayoutDirection)direction
{
return nil;
}
- (void)removeDictationResultPlaceholder:(id)placeholder willInsertResult:(BOOL)willInsertResult
{
}
- (void)replaceRange:(UITextRange *)range withText:(NSString *)text
{
}
- (NSArray *)selectionRectsForRange:(UITextRange *)range
{
return nil;
}
- (void)setBaseWritingDirection:(UITextWritingDirection)writingDirection forRange:(UITextRange *)range
{
}
- (void)setMarkedText:(NSString *)markedText selectedRange:(NSRange)selectedRange
{
}
- (NSString *)textInRange:(UITextRange *)range
{
return nil;
}
- (UITextRange *)textRangeFromPosition:(UITextPosition *)fromPosition toPosition:(UITextPosition *)toPosition
{
return nil;
}
I want a numeric keyboard without any textfield, I want to press a button and the keyboard will pop, is there an easy way to do it?
Or I need to build my own keyboard?
Thanks. :)
//
// EditingView.h
// TextEditing
//
// Created by Jeffrey Sambells on 10-04-21.
// Copyright 2010 TropicalPixels. All rights reserved.
//
#import <UIKit/UIKit.h>
#interface UIKeyInputExampleView : UIView <UIKeyInput> {
NSMutableString *textStore;
}
#property (nonatomic, retain) NSMutableString *textStore;
#end
//
// EditingView.m
// TextEditing
//
// Created by Jeffrey Sambells on 10-04-21.
// Copyright 2010 TropicalPixels. All rights reserved.
//
#import "UIKeyInputExampleView.h"
#implementation UIKeyInputExampleView
#synthesize textStore;
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
// Initialization code
self.textStore = [NSMutableString string];
[self.textStore appendString:#"Touch screen to edit."];
self.backgroundColor = [UIColor whiteColor];
}
return self;
}
- (void)dealloc {
[textStore dealloc];
[super dealloc];
}
#pragma mark -
#pragma mark Respond to touch and become first responder.
- (BOOL)canBecomeFirstResponder { return YES; }
-(void) touchesBegan: (NSSet *) touches withEvent: (UIEvent *) event {
[self becomeFirstResponder];
}
#pragma mark -
#pragma mark Drawing
- (void)drawRect:(CGRect)rect {
CGRect rectForText = CGRectInset(rect, 20.0, 20.0);
UIRectFrame(rect);
[self.textStore drawInRect:rectForText withFont:[UIFont fontWithName:#"Helvetica" size:24.0f]];
}
#pragma mark -
#pragma mark UIKeyInput Protocol Methods
- (BOOL)hasText {
if (textStore.length > 0) {
return YES;
}
return NO;
}
- (void)insertText:(NSString *)theText {
[self.textStore appendString:theText];
[self setNeedsDisplay];
}
- (void)deleteBackward {
NSRange theRange = NSMakeRange(self.textStore.length-1, 1);
[self.textStore deleteCharactersInRange:theRange];
[self setNeedsDisplay];
}
#end
This code may help you...
You need to implement UIKeyInput protocol. Reference
My source code download
------Updated--------
I am trying to implement a sidebar effect using CGAffineTransformMakeTranslate simulate slide-in and slide-out. I want to make my sidebar as a scrollview so it could be add more data but it can not scroll at all.
Here is my code:
SidebarView is a UITableView
#import "SidebarView.h"
#interface SidebarView ()
#property (nonatomic, readwrite) CGFloat offsetX;
#end
#implementation SidebarView
#pragma mark - Initilization
- (void)setup {
// do initilization here
self.offsetX = self.frame.size.width;
[self registerClass:[UITableViewCell class] forCellReuseIdentifier:#"sidebarCell"];
}
- (void)awakeFromNib {
[self setup];
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
[self setup];
return self;
}
#pragma mark - Custom function
- (void)show {
self.transform = CGAffineTransformMakeTranslation(-self.offsetX, 0);
}
- (void)hide {
self.transform = CGAffineTransformMakeTranslation(-self.offsetX, 0);
}
And my view controller:
#import "ViewController.h"
#import "SidebarView.h"
#interface ViewController () <UITableViewDataSource>
#property (nonatomic) BOOL isMenuHide;
#property (nonatomic, strong) SidebarView *sidebarView;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.isMenuHide = YES;
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
if (self.sidebarView) {
self.sidebarView = nil;
}
if (self.view) {
self.view = nil;
}
}
- (SidebarView *)sidebarView {
if (!_sidebarView) {
CGRect frame = [[UIScreen mainScreen] bounds];
frame.size.width /= 2;
_sidebarView = [[SidebarView alloc] initWithFrame:frame];
_sidebarView.transform = CGAffineTransformMakeTranslation(-_sidebarView.offsetX, 0);
_sidebarView.contentSize = CGSizeMake(320, 960);
_sidebarView.scrollEnabled = YES;
_sidebarView.showsVerticalScrollIndicator = YES;
_sidebarView.dataSource = self;
}
return _sidebarView;
}
#define ANIMATE_DURATION 0.5
- (IBAction)showMenu:(UIBarButtonItem *)sender {
if (self.isMenuHide) {
[self.view addSubview:self.sidebarView];
[UIView animateWithDuration:ANIMATE_DURATION animations:^{
[self.sidebarView show];
self.view.transform = CGAffineTransformMakeTranslation(self.sidebarView.offsetX, 0);
}];
} else {
[UIView animateWithDuration:ANIMATE_DURATION animations:^{
[self.sidebarView hide];
self.view.transform = CGAffineTransformMakeTranslation(0, 0);
} completion:^(BOOL finished) {
[self.sidebarView removeFromSuperview];
}];
}
self.isMenuHide = !self.isMenuHide;
}
#pragma mark - UITableView Datasource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 11;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"sidebarCell"];
cell.textLabel.text = #"Bingo";
return cell;
}
#end
Please tell my "why my scrollview cannot scroll" thanks.
contentSize needs to be set to the size of the content being contained, not the size of the frame in which it sits.
I don't know if your code has other problems, but that's the most terminal one.