ios - 复制 iOS 邮件撰写界面的行为,但 View 不跟随光标

标签 ios objective-c uitableview uiscrollview uitextview

我一直致力于创建 Apple 的邮件撰写 View 的副本,以便可以通过 API 调用而不是 iOS 使用的标准电子邮件发送来发送消息。

到目前为止一切顺利,但是当我在消息正文中键入内容时,光标将开始在键盘下方消失。

我不确定这是否与我设置约束的方式有关,或者是否与其他原因有关,但现在它没有按预期工作。

这是到目前为止我为 View Controller 准备的相关代码...

- (void)viewDidLoad {
    [super viewDidLoad];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    self.bodyTextView.delegate = self;

    UIBarButtonItem *cancelBarButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelButton:)];
    UIBarButtonItem *sendBarButton = [[UIBarButtonItem alloc] initWithTitle:@"Send" style:UIBarButtonItemStyleDone target:self action:@selector(sendButton:)];
    self.navigationItem.leftBarButtonItem = cancelBarButton;
    self.navigationItem.rightBarButtonItem = sendBarButton;
    self.navigationItem.title = @"Compose Email";

    self.recipients = [NSMutableArray array];

    if (self.contactID) {
        [self.recipients addObject:@{@"contact_id":self.contactID}];
    } else {
        [self.recipients addObject:@{@"name":self.name, @"address":self.emailAddress}];
    }

    [self prepareTableView];

    self.tableView.rowHeight = UITableViewAutomaticDimension;
}

- (void)prepareTableView {
    if (!self.sectionTitles) {
        self.sectionTitles = [NSMutableArray array];
    }

    [self.sectionTitles addObject:@"To"];
    [self.sectionTitles addObject:@"Subject"];
    [self.sectionTitles addObject:@"MessageBody"];
}


#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return self.sectionTitles.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 1;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [UITableViewCell new];

    NSString *sectionTitle = [self.sectionTitles objectAtIndex:indexPath.section];

    if ([sectionTitle isEqualToString:@"To"]) {
        EmailToTableViewCell *toCell = [tableView dequeueReusableCellWithIdentifier:@"EmailToCell"];
        toCell.selectionStyle = UITableViewCellSelectionStyleNone;
        toCell.toTextField.text = self.name;
        toCell.toTextField.accessibilityLabel = @"Message Recipient";

        cell = toCell;
    }

    if ([sectionTitle isEqualToString:@"Subject"]) {
        EmailSubjectTableViewCell *subjectCell = [tableView dequeueReusableCellWithIdentifier:@"EmailSubjectCell"];
        subjectCell.selectionStyle = UITableViewCellSelectionStyleNone;

        self.subjectField = subjectCell.emailSubjectTextField;
        self.subjectField.accessibilityLabel = @"Message Subject";

        if (self.subject) {
            self.subjectField.text = self.subject;
        }

        cell = subjectCell;
    }

    if ([sectionTitle isEqualToString:@"MessageBody"]) {
        self.bodyCell = [tableView dequeueReusableCellWithIdentifier:@"EmailBodyCell"];
        self.bodyCell.selectionStyle = UITableViewCellSelectionStyleNone;

        self.bodyTextView = self.bodyCell.emailBodyTextView;
        self.bodyTextView.accessibilityLabel = @"Message Body";

        if (self.messageBody) {
            self.bodyTextView.text = self.messageBody;
        }

        cell = self.bodyCell;
    }

    return cell;
}

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 2) {
        return self.bodyTextView.frame.size.height + 8;
    } else {
        return 44;
    }
}

#pragma mark - UITextViewDelegate

- (void)textViewDidChange:(UITextView *)textView {
    [self.tableView beginUpdates];
    [self.tableView endUpdates];

    [self scrollToCursorForTextView:textView];
}

- (void)scrollToCursorForTextView: (UITextView*)textView {
    CGRect cursorRect = [textView caretRectForPosition:textView.selectedTextRange.end];

    cursorRect = [textView convertRect:cursorRect toView:self.view];
    cursorRect = [self.tableView convertRect:cursorRect fromView:textView];

    if (![self rectVisible:cursorRect]) {
        cursorRect.size.height += 16;
        [self.tableView scrollRectToVisible:cursorRect animated:YES];
    }
}

- (BOOL)rectVisible: (CGRect)rect {
    CGRect visibleRect;
    visibleRect.origin = self.tableView.contentOffset;
    visibleRect.origin.y += self.tableView.contentInset.top;
    visibleRect.size = self.tableView.bounds.size;
    visibleRect.size.height -= self.tableView.contentInset.top + self.tableView.contentInset.bottom;

    return CGRectContainsRect(visibleRect, rect);
}

- (void)keyboardWillShow:(NSNotification*)notification {
    NSDictionary* info = [notification userInfo];
    CGSize keyboardSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
    self.tableView.contentInset = UIEdgeInsetsMake(0.0, 0.0, keyboardSize.height, 0.0);
    self.tableView.scrollIndicatorInsets = self.tableView.contentInset;
}

- (void)keyboardWillHide:(NSNotification*)aNotification {
    self.tableView.contentInset = UIEdgeInsetsZero;
}

这是我的 UI...

Overall UI

Constraints for UITextView

Interface builder side bar view

最后,这是一个视频链接,显示了到目前为止发生的事情。请注意,我已经减小了作为 UITableView 中的单元格之一的 UITextView 的最小大小,以便更好地了解正在发生的事情。

Link to video of problem

如果我遗漏了任何可能有助于解决此问题的信息,请告诉我,我会将其添加到问题中。

最佳答案

UITableViewController 自动处理这个。尝试删除所有额外的代码和计算。确保设置了 UITextView 前导、尾随、顶部和底部约束。

如果您使用 UITableView,那么您必须使用键盘显示/隐藏通知来完成所有这些计算。

关于ios - 复制 iOS 邮件撰写界面的行为,但 View 不跟随光标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45716893/

相关文章:

objective-c - Cocoa应用程序系统重启

ios - UITableview 的单元格中的重复数据

swift - TableView ReloadSection 崩溃了吗?

iphone - 将 UITableView 的相同默认背景设置为自定义 View Controller

ios - 为什么我的备用图标在 iPhone 上有效,但在 iPad 上却无效?

ios - 在没有用户交互的情况下发送电子邮件

ios - 在 UIView 上绘制图像,并打一个透明孔可以看到下面的 UIView

ios - 仅将 XML 中的 20 个最近项目添加到 NSMutableArray

objective-c - 奇怪的 XCode 4.2 和核心数据行为

ios - 快速 fatal error : unexpectedly found nil while unwrapping an Optional value