【发布时间】:2015-04-11 20:30:45
【问题描述】:
我有一个带有自定义字体的 UITextField,在 Swift 更新到 1.2 和 2.0 之前一切正常。之后,每次我尝试编辑文本字段时,它都会将其字体更改为另一种看起来像是 Times New Roman 的字体。有人有这方面的经验吗?
【问题讨论】:
-
这是 Swift 的错吗?如果有的话,这是一个 UIKit 框架错误。你向 Apple 报告了吗?
我有一个带有自定义字体的 UITextField,在 Swift 更新到 1.2 和 2.0 之前一切正常。之后,每次我尝试编辑文本字段时,它都会将其字体更改为另一种看起来像是 Times New Roman 的字体。有人有这方面的经验吗?
【问题讨论】:
当使用按钮操作切换 UiTextField 的 secureTextEntry 时,我遇到了一个奇怪的字体更改其大小和字体类型的情况。 必须使用这些代码行显式管理 UiTextField 的字体:
password.font = UIFont(name: "systemFont", size: 14)
password.font = UIFont.systemFontOfSize(14)
显示密码按钮中使用的完整代码:
//Function associated with the button for show password option
@IBAction func switchShowPasswordAction(sender: AnyObject) {
if showPassword{
showPassword = false
password.secureTextEntry = !showPassword
}else{
showPassword = true
password.secureTextEntry = !showPassword
}
//Changing font fix
password.font = UIFont(name: "systemFont", size: 14)
password.font = UIFont.systemFontOfSize(14)
}
【讨论】:
password.font = UIFont(name: "systemFont", size: 14) 。我猜是因为没有名为systemFont的字体,系统会回退到默认的系统字体。不过看起来很hacky。
if let currentFont = passwordTextField.font { passwordTextField.font = nil; passwordTextField.font = currentFont; }
在切换 secureTextEntry 标志后使用自定义字体属性设置 defaultTextAttributes
NSDictionary *attrsDictionary =
@{ NSFontAttributeName://customfont};
_passwordtextfield.defaultTextAttributes = attrsDictionary;
【讨论】:
我必须将以下解决方案与最新的 Xcode 7.1.1 一起应用,这在我的情况下确实有效,我怀疑这个问题是框架问题。
- (IBAction)btnPasswordShowAction:(id)sender {
self.txtPassword.secureTextEntry = !self.txtPassword.secureTextEntry;
NSString *tmpString = self.txtPassword.text;
self.txtPassword.text = @" ";
self.txtPassword.text = tmpString;
[self.txtPassword setFont:nil];
self.txtPassword.font = [UIFont fontWithName:@"OpenSans-Regular" size:16.0];
}
#pragma mark - Textfield Delegate Methods
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[self.txtPassword setFont:nil];
self.txtPassword.font = [UIFont fontWithName:@"OpenSans-Regular" size:16.0];
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
[self.txtPassword setFont:nil];
self.txtPassword.font = [UIFont fontWithName:@"OpenSans-Regular" size:16.0];
return YES;
}
【讨论】:
由于我使用了自定义字体,我们需要保留原始字体。创建UITextField的扩展:
extension UITextField {
func enablePasswordModeWithShowHide() {
secureTextEntry = false
let showButton = UIButton(type: UIButtonType.System)
showButton.setTitle("HIDE", forState: .Normal)
showButton.titleLabel?.textAlignment = .Right
showButton.sizeToFit()
rightView = showButton
rightViewMode = .Always
showButton.addTarget(self, action: "handleShowHideTapped", forControlEvents: .TouchUpInside)
showButton.tintColor = UIColor.blackColor()
}
func handleShowHideTapped() {
secureTextEntry = !secureTextEntry
let font = self.font
self.font = nil
self.font = font
if let oldText = text {
text = "";
text = oldText;
}
if let button = rightView as? UIButton {
button.setTitle(secureTextEntry ? "SHOW" : "HIDE", forState: .Normal)
button.sizeToFit()
}
}
}
可以这样实现的地方:
passwordTextField.enablePasswordModeWithShowHide()
【讨论】:
我遇到了同样的问题并找到了解决方案。问题归结为setSecureTextEntry 在设置字体时更改字体,而在取消设置时不更改回字体。事实上,只要您的UITextField 有第一响应者,您就永远无法改回字体。
诀窍是在您拨打setSecureTextEntry: 之前先拨打resignFirstResponder,然后再拨打becomeFirstResponder。这将有效(从 iOS 9.2 开始),但它会触发键盘显示/隐藏动画并导致屏幕“抖动”。要解决这个问题,您还需要终止键盘动画。
这是我的完整解决方案:
- (void)setSecureTextEntry:(BOOL)secureTextEntry {
__weak typeof(self) weakSelf = self;
[UIView performWithoutAnimation:^{
BOOL resumeResponder = NO;
if([[weakSelf textEntryField] isFirstResponder]) {
resumeResponder = YES;
[[weakSelf textEntryField] resignFirstResponder];
}
[[weakSelf textEntryField] setSecureTextEntry:secureTextEntry];
if(resumeResponder) {
[[weakSelf textEntryField] becomeFirstResponder];
}
}];
}
PS:这不是 Swift 错误。这是一个 UIKit 错误。我对 Objective-C 也有同样的问题。
【讨论】:
所有这些答案都非常有效,但考虑到我使用的是自定义字体,我不得不使用不同的解决方案来获得所需的结果。
您需要在情节提要检查器窗格中为 UITextField 设置文本字段 attributed,如下所示:
然后,在代码中,您需要管理可见性的切换,每次设置属性文本,以确保其格式正确。我也在场上辞去了FirstResponder()的职务,只是为了处理一些我还没有弄清楚的定位故障。
func toggleShowPass() {
self.showing = !showing
txtpassword.secureTextEntry = !showing
textFieldPassword.resignFirstResponder()
let string = textFieldPassword.text!
let attrString = NSMutableAttributedString(string: string)
textFieldPassword.addAttribute(NSFontAttributeName, value: UIFont(name: "AvenirNext-Regular", size: 16.0)!, range: NSMakeRange(0, string.characters.count))
textFieldPassword.attributedText = attrString
}
【讨论】: