jkh*_*jkh 40 space objective-c uitextfield ios ios7
在我的iPad应用程序中,我注意到iOS 6和iOS 7与UITextFields之间存在不同的行为.
我创建UITextField如下:
UIButton *theButton = (UIButton*)sender;
UITextField *textField = [[UITextField alloc] initWithFrame:[theButton frame]];
[textField setDelegate:self];
[textField setContentVerticalAlignment:UIControlContentVerticalAlignmentCenter];
[textField setContentHorizontalAlignment:UIControlContentHorizontalAlignmentRight];
textField.textAlignment = UITextAlignmentRight;
textField.keyboardType = UIKeyboardTypeDefault;
...
[textField becomeFirstResponder];
Run Code Online (Sandbox Code Playgroud)
在iOS 6中,当我输入"hello world"时,当我在"你好"之后点击空格键时,光标会前进一个空格.
在iOS 7中,当我按下空格键时光标不会前进.但是,当我在"世界"中键入"w"时,它会显示空格和w.
在iOS 7中按空格键时,如何使光标前进?
更新:
如果我将textField.textAlignment更改为UITextAlignmentLeft,则该空间将显示在iOS 7中.如果可能,我希望将其保持正确对齐.
tri*_*tan 44
这将是一个黑客攻击,但如果你真的需要这样看iOS6的方式,你可以在写入时用不间断的空间替换空间.它的处理方式不同.示例代码可能如下所示:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
// only when adding on the end of textfield && it's a space
if (range.location == textField.text.length && [string isEqualToString:@" "]) {
// ignore replacement string and add your own
textField.text = [textField.text stringByAppendingString:@"\u00a0"];
return NO;
}
// for all other cases, proceed with replacement
return YES;
}
Run Code Online (Sandbox Code Playgroud)
如果不清楚,textField:shouldChangeCharactersInRange:replacementString:是一个UITextFieldDelegate协议方法,所以在你的例子中,上面的方法将在viewcontroller中指定[textField setDelegate:self].
如果你希望你的常规空格后面,你会明显还需要记住更换的出现将文本转换回@"\u00a0"与@" "获取串出文本字段时.
git*_*rik 13
你必须用不间断的空格替换普通空格.最好为此更改事件触发操作:
在某处为UIControlEventEditingChanged文本字段上的事件添加操作:
[myTextField addTarget:self action:@selector(replaceNormalSpacesWithNonBreakingSpaces)
forControlEvents:UIControlEventEditingChanged];
Run Code Online (Sandbox Code Playgroud)然后实现replaceNormalSpacesWithNonBreakingSpaces方法:
- (void)replaceNormalSpacesWithNonBreakingSpaces
{
self.text = [self.text stringByReplacingOccurrencesOfString:@" "
withString:@"\u00a0"];
}
Run Code Online (Sandbox Code Playgroud)这比使用更安全textField:shouldChangeCharactersInRange:replacementString:,因为如果NO从这个方法返回,你实际上是在说不应该更改指定的文本.这将导致不会触发更改事件(如IBActions textFieldEditingChanged:或UITextField的UIControlEventEditingChanged事件).
如果要对所有UITextField进行此修复,则可以创建一个类别,在启动UITextField时添加这些事件操作.在下面的示例中,我还在编辑结束时将非中断空格更改回正常空格,以便在其他地方使用数据时不会出现非中断空格的可能问题.请注意,此示例使用方法调配,因此它可能看起来有点奇怪,但它是正确的.
头文件:
// UITextField+RightAlignedNoSpaceFix.h
#import <UIKit/UIKit.h>
@interface UITextField (RightAlignedNoSpaceFix)
@end
Run Code Online (Sandbox Code Playgroud)
实施文件:
// UITextField+RightAlignedNoSpaceFix.m
#import "UITextField+RightAlignedNoSpaceFix.h"
@implementation UITextField (RightAlignedNoSpaceFix)
static NSString *normal_space_string = @" ";
static NSString *non_breaking_space_string = @"\u00a0";
+(void)load
{
[self overrideSelector:@selector(initWithCoder:)
withSelector:@selector(initWithCoder_override:)];
[self overrideSelector:@selector(initWithFrame:)
withSelector:@selector(initWithFrame_override:)];
}
/**
* Method swizzles the initWithCoder method and adds the space fix
* actions.
*/
-(instancetype)initWithCoder_override:(NSCoder*)decoder
{
self = [self initWithCoder_override:decoder];
[self addSpaceFixActions];
return self;
}
/**
* Method swizzles the initWithFrame method and adds the space fix
* actions.
*/
-(instancetype)initWithFrame_override:(CGRect)frame
{
self = [self initWithFrame_override:frame];
[self addSpaceFixActions];
return self;
}
/**
* Will add actions on the text field that will replace normal
* spaces with non-breaking spaces, and replaces them back after
* leaving the textfield.
*
* On iOS 7 spaces are not shown if they're not followed by another
* character in a text field where the text is right aligned. When we
* use non-breaking spaces this issue doesn't occur.
*
* While editing, the normal spaces will be replaced with non-breaking
* spaces. When editing ends, the non-breaking spaces are replaced with
* normal spaces again, so that possible problems with non-breaking
* spaces won't occur when the data is used somewhere else.
*/
- (void)addSpaceFixActions
{
[self addTarget:self action:@selector(replaceNormalSpacesWithNonBreakingSpaces)
forControlEvents:UIControlEventEditingDidBegin];
[self addTarget:self action:@selector(replaceNormalSpacesWithNonBreakingSpaces)
forControlEvents:UIControlEventEditingChanged];
[self addTarget:self action:@selector(replaceNonBreakingSpacesWithNormalSpaces)
forControlEvents:UIControlEventEditingDidEnd];
}
/**
* Will replace normal spaces with non-breaking spaces.
*/
- (void)replaceNormalSpacesWithNonBreakingSpaces
{
self.text = [self.text stringByReplacingOccurrencesOfString:normal_space_string
withString:non_breaking_space_string];
}
/**
* Will replace non-breaking spaces with normal spaces.
*/
- (void)replaceNonBreakingSpacesWithNormalSpaces
{
self.text = [self.text stringByReplacingOccurrencesOfString:non_breaking_space_string
withString:normal_space_string];
}
@end
Run Code Online (Sandbox Code Playgroud)
Jac*_*ong 11
以上所有答案都很棒,非常具有指示性!尤其是非常感谢的意思,问题的下面答案.这是经过测试的Swift 2.0版本.记得到指定的代表给出UITextField到你的ViewController!快乐的编码.
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
if (textField == self.desiredTextField) {
var oldString = textField.text!
let newRange = oldString.startIndex.advancedBy(range.location)..<oldString.startIndex.advancedBy(range.location + range.length)
let newString = oldString.stringByReplacingCharactersInRange(newRange, withString: string)
textField.text = newString.stringByReplacingOccurrencesOfString(" ", withString: "\u{00a0}");
return false;
} else {
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
-
这是Swift 3!
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if (textField == self.textfield) {
let oldString = textField.text!
let newStart = oldString.index(oldString.startIndex, offsetBy: range.location)
let newEnd = oldString.index(oldString.startIndex, offsetBy: range.location + range.length)
let newString = oldString.replacingCharacters(in: newStart..<newEnd, with: string)
textField.text = newString.replacingOccurrences(of: " ", with: "\u{00a0}")
return false;
} else {
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个始终有效的解决方案,也适用于粘贴和编辑(即,您可以添加/删除具有多个空格的文本).
- (BOOL)textField:(UITextField*)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString*)string
{
textField.text = [textField.text stringByReplacingCharactersInRange:range withString:string];
textField.text = [textField.text stringByReplacingOccurrencesOfString:@" " withString:@"\u00a0"];
return NO;
}
Run Code Online (Sandbox Code Playgroud)
不要担心stringByReplacingOccurrencesOfString每次都做的表现; UI中的文本相对于CPU速度非常短.
然后当你真的想从文本字段中获取值时:
NSString* text = [textField.text stringByReplacingOccurrencesOfString:@"\u00a0" withString:@" "];
Run Code Online (Sandbox Code Playgroud)
所以这是一个很好的对称.
小智 5
我想出了一个解决方案,它将UITextField类子类化并执行交换,而无需在任何地方复制和粘贴代码.这也避免了使用方法sizzle来解决这个问题.
@implementation CustomTextField
-(id) initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if( self ) {
[self addSpaceFixActions];
}
return self;
}
- (void)addSpaceFixActions {
[self addTarget:self action:@selector(replaceNormalSpaces) forControlEvents:UIControlEventEditingChanged];
[self addTarget:self action:@selector(replaceBlankSpaces) forControlEvents:UIControlEventEditingDidEnd];
}
//replace normal spaces with non-breaking spaces.
- (void)replaceNormalSpaces {
if (self.textAlignment == NSTextAlignmentRight) {
UITextRange *textRange = self.selectedTextRange;
self.text = [self.text stringByReplacingOccurrencesOfString:@" " withString:@"\u00a0"];
[self setSelectedTextRange:textRange];
}
}
//replace non-breaking spaces with normal spaces.
- (void)replaceBlankSpaces {
self.text = [self.text stringByReplacingOccurrencesOfString:@"\u00a0" withString:@" "];
}
Run Code Online (Sandbox Code Playgroud)