【问题标题】:iOS 7 UITextView vertical alignmentiOS 7 UITextView 垂直对齐
【发布时间】:2013-10-28 09:42:15
【问题描述】:

我的可编辑UITextView(放置在UISplitView 内的一个简单的UIViewController 中,充当UITextView 的代表)怎么可能不是从一开始就显示文本,而是在6-7 行之后显示文本?

我没有设置任何特定的自动布局或类似的东西,试图删除文本没有帮助(所以没有隐藏字符或其他东西)。

我在 iPad 上使用 iOS 7,故事板看起来不错... iOS模拟器和真实设备上的问题是一样的。我要生气了:P

这里有一些代码。这是 ViewController viewDidLoad()

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.itemTextField.delegate = self;
    self.itemTextField.text = NSLocalizedString(@"NEWITEMPLACEHOLDER", nil);
    self.itemTextField.textColor = [UIColor lightGrayColor]; //optional
}

这里是UITextView 的重写函数,我正在使用我在 StackOverflow 上找到的一些代码来模拟视图的占位符(iPhone 版本的情节提要上的相同内容可以正常工作)...

// UITextView placeholder
- (void)textViewDidBeginEditing:(UITextView *)textView
{
    if ([textView.text isEqualToString:NSLocalizedString(@"NEWITEMPLACEHOLDER", nil)]) {
        textView.text = @"";
        textView.textColor = [UIColor blackColor]; //optional
    }
    [textView becomeFirstResponder];
}

- (void)textViewDidEndEditing:(UITextView *)textView
{
    if ([textView.text isEqualToString:@""]) {
        textView.text = NSLocalizedString(@"NEWITEMPLACEHOLDER", nil);
        textView.textColor = [UIColor lightGrayColor]; //optional
    }
    [textView resignFirstResponder];
}

-(void)textViewDidChange:(UITextView *)textView
{
    int len = textView.text.length;
    charCount.text = [NSString stringWithFormat:@"%@: %i",  NSLocalizedString(@"CHARCOUNT", nil),len];
}

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
    return YES;
}

【问题讨论】:

  • 浅蓝色是UITextVIew的背景色?
  • 是的,我在故事板中设置了它,以便在屏幕截图中清晰。顺便说一句,即使使用默认背景颜色也存在问题。
  • 这已从原始问题“如何垂直对齐 UITextView”进行了重大修改。

标签: ios objective-c ipad uitextview vertical-alignment


【解决方案1】:

受 Kiattisak 的启发,我将垂直对齐实现为 UITextView 之上的一个类别,以便您可以控制旧版 UITextView垂直对齐。

您可以通过gist here 找到它。

【讨论】:

  • 当 VC 被释放时,一定要移除键值观察者
【解决方案2】:

使用 -observerForKeyPathcontentSize KeyPath

在我的博客中查看一些代码(不要专注于泰语语言)

http://www.macbaszii.com/2012/10/ios-dev-uitextview-vertical-alignment.html

【讨论】:

    【解决方案3】:

    Tanguy.G 答案的 Swift 版本:

    if(UIDevice.currentDevice().systemVersion >= "7.0") {
                self.automaticallyAdjustsScrollViewInsets = false; // Avoid the top UITextView space, iOS7 (~bug?)
      }
    

    【讨论】:

    • 还要注意,您经常需要调用布局:view.layoutIfNeeded()。这很烦人,而且在 iOS 中做得非常糟糕。
    【解决方案4】:

    我在使用 iOS 8.1 时遇到了同样的问题,但这些建议都不起作用。

    所做的工作是进入情节提要,并拖动我的UITableViewUITextView,使其不再是我屏幕UIView 的第一个子视图。

    http://www.codeproject.com/Tips/852308/Bug-in-XCode-Vertical-Gap-Above-UITableView

    这似乎与将 UIView 嵌入到 UINavigationController 中有关。

    错误?漏洞 ?我说的是“bug”吗……?

    ;-)

    【讨论】:

      【解决方案5】:

      这是一个相当普遍的问题,所以我会创建一个简单的 UITextView 子类,以便您可以重复使用它并在 IB 中使用它。

      我会改用 contentInset,确保优雅地处理 contentSize 大于 textView 边界的情况

      @interface BSVerticallyCenteredTextView : UITextView
      
      @end
      
      @implementation BSVerticallyCenteredTextView
      
      - (id)initWithFrame:(CGRect)frame
      {
          if (self = [super initWithFrame:frame])
          {
              [self addObserver:self forKeyPath:@"contentSize" options:  (NSKeyValueObservingOptionNew) context:NULL];
          }
          return self;
      }
      
      - (id)initWithCoder:(NSCoder *)aDecoder
      {
          if (self = [super initWithCoder:aDecoder])
          {
              [self addObserver:self forKeyPath:@"contentSize" options:  (NSKeyValueObservingOptionNew) context:NULL];
          }
          return self;
      }
      
      -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
      {
          if ([keyPath isEqualToString:@"contentSize"])
          {
              UITextView *tv = object;
              CGFloat deadSpace = ([tv bounds].size.height - [tv contentSize].height);
              CGFloat inset = MAX(0, deadSpace/2.0);
              tv.contentInset = UIEdgeInsetsMake(inset, tv.contentInset.left, inset, tv.contentInset.right);
          }  
      }
      
      - (void)dealloc
      {
          [self removeObserver:self forKeyPath:@"contentSize"];
      }
      
      @end
      

      【讨论】:

        【解决方案6】:

        我也遇到了同样的问题。

        通过禁用自动滚动视图插入调整来解决它:

        if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")){
            self.automaticallyAdjustsScrollViewInsets = NO; // Avoid the top UITextView space, iOS7 (~bug?)
        }
        

        【讨论】:

        • 谢谢!这是类似故事板属性的“代码方式”!
        【解决方案7】:

        在传递文本后尝试调用-sizeToFit。这个答案可能对Vertically align text within a UILabel 有用。
        [更新]
        我更新了这个答案,使其更具可读性。
        问题在于,从 iOS7 开始,UINavigationController 或 UITabbarController 等容器视图控制器可以更改滚动视图(或从其继承的视图)的内容插入,以避免内容重叠。仅当滚动视图是主视图或第一个子视图时才会发生这种情况。为避免这种情况,您应该通过将automaticallyAdjustsScrollViewInsets 设置为 NO 来禁用此行为,或者重写此方法以返回 NO。

        【讨论】:

        • 不工作。 UITextView 的大小调整为 30 x 20 像素,并且不显示任何文本。
        • 你在使用属性字符串吗?
        • 好吧,也许 lorik 给我指出了正确的方向。插入是由于 UITextField 具有 scrool 功能,因为 iOS7 在 sotryboard 中每种滚动视图都会自动插入状态栏+导航栏的大小(在 UINavController 中)。可能在这里你在顶部放置了一个约束,它修复了“顶部距离”,但你没有取消选择自动边缘选项。所以检查这个VC的故事板并取消选择调整滚动视图插入选项。
        【解决方案8】:

        检查-viewDidLoad中textView的顶部内容插入:

        NSLog(@"NSStringFromUIEdgeInsets(self.itemTextField.contentInset) = %@", NSStringFromUIEdgeInsets(self.itemTextField.contentInset));
        

        如果它不为零,则在情节提要中重置它

        【讨论】:

        • NSStringFromUIEdgeInsets(self.itemTextField.contentInset) = {0, 0, 0, 0} 不走运。
        • 记录self.itemTextField.contentOffset
        • self.itemTextField.contentOffset = null
        • 更改 field.contentOffset 是唯一对我有用的解决方案。 (iOS 7.0)
        猜你喜欢
        • 1970-01-01
        • 2013-04-26
        • 1970-01-01
        • 2013-06-06
        • 2013-09-27
        • 2019-10-12
        • 2012-09-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多