iOS 仿即刻評論輸入框帶圖片
效果圖
功能點
- 輸入框自適應高度
- 達到某個高度高度不再變化
- 底部顯示圖片
- 鍵盤的彈起和收起適應
用到的控制元件
UITextView
UIImageView
UIScrollView
UIButton
UIView
思路
UIScrollView
的contentSize
為UITextView
的文字高度 +UIImageView
的高度UIScrollView
的最大高度為UITextView
顯示最多行數的文字高度,加上圖片的高度
具體步驟
建立
CommentView
進行封裝好,CommentView
需要實現的功能為 UI 介面的搭建、鍵盤彈起和收起的適應,選擇圖片之後對介面約束的一些更新操作commentView.h
需要的一些屬性
@property (nonatomic, weak) UIViewController *contoller; /**< 將控制器傳入,跳轉相簿 */
@property (nonatomic, weak) MASConstraint *bottomConstraint; /**< CommentView 的底部約束,鍵盤彈起和收起時更新約束 */
-
commentView.m
屬性
@property (nonatomic, strong) UIScrollView *contentScrollView; /**< 評論內容 */
@property (nonatomic, strong) UIView *contentView; /**< 內容檢視 */
@property (nonatomic, strong) UIImageView *imageView; /**< 圖片 */
@property (nonatomic, strong) GPTextView *textView; /**< 輸入框 */
@property (nonatomic, strong) UIButton *chooseImageButton; /**< 選擇圖片按鈕 */
@property (nonatomic, assign) CGFloat imageHeight; /**< 圖片高度 */
@property (nonatomic, assign) CGFloat commentHeight; /**< 評論框的高度 */
-
GPTextView
是自定義的一個類,繼承於UITextView
,GPTextView.h
檔案
typedef void (^ChangeTextHeight)(NSString *text, CGFloat height, BOOL autoChangeHeight); /**< 改變輸入框高度回撥 */
@interface GPTextView : UITextView
#pragma mark - Property
@property (nonatomic, copy) NSString *placeholder; /**< 佔位文字 */
@property (nonatomic, strong) UIColor *placeholderColor; /**< 佔位文字顏色 */
@property (nonatomic, strong) UIFont *placeholderFont; /**< 佔位文字字型大小 */
@property (nonatomic, assign) NSInteger numberOfLines; /**< 行數 0-無限行 */
#pragma mark - Method
/**
改變輸入框的高度
*/
- (void)textHeightDidChange:(ChangeTextHeight)changeText;
@end
-
GPTextView.m
屬性
@property (nonatomic, assign) CGFloat textHeight; /**< 文字高度 */
@property (nonatomic, assign) CGFloat maxTextHeight; /**< 文字最大高度 */
@property (nonatomic, strong) UILabel *placeholderLabel; /**< 佔位文字 */
@property (nonatomic, assign) BOOL autoChangeHeight; /**< 是否需要自動改變高度 */
@property (nonatomic, copy) ChangeTextHeight changeTextHeightBlock;
其中對 GPTextView
的 placeholder
實現這裡就不描述了,主要是描述一下輸入框的自適應高,首先註冊 UITextViewTextDidChangeNotification
通知,監聽 textView
輸入文字的改變;然後在監聽方法裡面進行判斷是否需要改變 textView
的高度
- (void)textDidChange {
self.placeholderLabel.hidden = self.text.length > 0 ? YES : NO; // 佔位文字的隱藏和顯示
NSInteger height = ceilf([self sizeThatFits:CGSizeMake(self.bounds.size.width, MAXFLOAT)].height); // 計算出當前文字高度
if (self.textHeight != height) { // 高度不一樣,行數改變了
// 是否需要改變 CommentView 的高度
self.autoChangeHeight = height <= self.maxTextHeight && self.maxTextHeight > 0;
self.textHeight = height;
if (self.changeTextHeightBlock) {
self.changeTextHeightBlock(self.text, self.textHeight, self.autoChangeHeight);
}
}
}
在 GPTextView
中主要操作就是這些,下面回到 commentView.m
中
- 對鍵盤的彈起和收起進行監聽
- (void)addObserver {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardChange:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardChange:) name:UIKeyboardWillHideNotification object:nil];
}
監聽方法實現
- (void)keyboardChange:(NSNotification *)notifi {
NSDictionary *userInfo = notifi.userInfo;
CGFloat duration = [[userInfo valueForKeyPath:@"UIKeyboardAnimationDurationUserInfoKey"] floatValue];
CGFloat keyboardHeight = [[userInfo valueForKeyPath:@"UIKeyboardFrameEndUserInfoKey"] CGRectValue].size.height; /**< 鍵盤的高度 */
if ([notifi.name isEqualToString:UIKeyboardWillShowNotification]) {
// 鍵盤彈起
[self updateBottomConstraintsWithHeight:keyboardHeight duration:duration];
} else if ([notifi.name isEqualToString:UIKeyboardWillHideNotification]) {
// 鍵盤收起
[self updateBottomConstraintsWithHeight:0 duration:duration];
}
}
/**
更新底部約束
*/
- (void)updateBottomConstraintsWithHeight:(CGFloat)height duration:(CGFloat)duration {
self.bottomConstraint.offset(-height);
[UIView animateWithDuration:duration animations:^{
[self.superview layoutIfNeeded];
}];
}
其中 bottomConstraint
是在新增 commentView
時,設定的底部約束的時候賦值好,這個屬性在 commentView.h
// 輸入框
[self.commentView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.equalTo(self.view);
self.commentView.bottomConstraint = make.bottom.equalTo(self.view).offset(0);
make.height.mas_equalTo(30);
}];
這樣,鍵盤彈起和收起適配,就不用在外面去控制了
- 輸入文字,高度改變,實現
textHeightDidChange
這個方法
[_textView textHeightDidChange:^(NSString *text, CGFloat height, BOOL autoChangeHeight) {
[wkSelf updateHeightWithHeight:height autoChangeHeight:autoChangeHeight];
}];
updateHeightWithHeight:autoChangeHeight
方法實現
- (void)updateHeightWithHeight:(CGFloat)height autoChangeHeight:(BOOL)autoChangeHeight {
CGFloat imageHeight = self.imageView.image ? self.imageHeight : 0;
if (autoChangeHeight) {
// 設定輸入框的高度
[self mas_updateConstraints:^(MASConstraintMaker *make) {
make.height.mas_equalTo(height + imageHeight);
}];
}
// 設定文字可滾動範圍
[self.contentView mas_updateConstraints:^(MASConstraintMaker *make) {
make.height.mas_equalTo(height + imageHeight);
}];
[self.textView mas_updateConstraints:^(MASConstraintMaker *make) {
make.height.mas_equalTo(height);
}];
[self layoutIfNeeded];
}
當 autoChangeHeight
為 YES
時,才對 commentView
的高度進行改變,否則只更新 textView
的高度和 scrollView
的 contentSize
屬性。
- 選擇圖片的時候,如果是第一次選擇圖片
commentView
的高度就需要改變,在imagePickerController:didFinishPickingMediaWithInfo
中進行操作
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
UIImage *image = [info valueForKeyPath:@"UIImagePickerControllerOriginalImage"];
BOOL autoChangeHeight = self.imageView.image ? NO : YES; // 是否需要改變高度 第一次選擇圖片 YES 切換圖片 NO
self.imageView.image = image;
[self layoutIfNeeded];
if (autoChangeHeight) {
[self.imageView mas_updateConstraints:^(MASConstraintMaker *make) {
make.height.mas_equalTo(self.imageHeight);
}];
BOOL isMoreThree = CGRectGetHeight(self.textView.frame) > CGRectGetHeight(self.contentScrollView.frame);
if (isMoreThree) {
// 設定輸入框的高度
[self mas_updateConstraints:^(MASConstraintMaker *make) {
make.height.mas_equalTo(CGRectGetHeight(self.contentScrollView.frame) + self.imageHeight);
}];
// 設定文字可滾動範圍
[self.contentView mas_updateConstraints:^(MASConstraintMaker *make) {
make.height.mas_equalTo(CGRectGetHeight(self.textView.frame) + self.imageHeight);
}];
[self.contentScrollView setContentOffset:CGPointMake(0, self.contentScrollView.contentSize.height - CGRectGetHeight(self.contentScrollView.frame)) animated:YES];
} else {
[self updateHeightWithHeight:self.textView.frame.size.height autoChangeHeight:autoChangeHeight];
}
}
[self layoutIfNeeded];
[picker dismissViewControllerAnimated:YES completion:nil];
}
以上就是仿照即刻 App 輸入框的一個實現
相關文章
- 仿IOS底部彈框iOS
- iOS Swift 仿微信聊天圖片顯示iOSSwift
- iOS Swift 輸入框限制長度iOSSwift
- iOS清除輸入框內陰影iOS
- iOS 防止輸入時鍵盤覆蓋掉輸入框iOS
- ReactNative仿支付寶付款密碼輸入框React密碼
- iOS開發之定製輸入框iOS
- 直播帶貨原始碼,評論框自動控制高度原始碼
- 專案需求討論-仿ios底部彈框實現及分析iOS
- Android仿滴滴出行驗證碼輸入框效果Android
- ios OC 輸入框禁止輸入空格/去掉空格/只能輸入字母和數字iOS
- 瀏覽器自帶資訊確認框和提示輸入框瀏覽器
- 仿即刻的點贊滾動放大波紋圖示
- iOS 文字輸入框隨鍵盤上移iOS
- android自定義仿微信、支付寶 密碼輸入框Android密碼
- Qt 實現文字輸入框,帶字數限制QT
- Flutter 密碼輸入框 驗證碼輸入框Flutter密碼
- react輸入框輸入中文bugReact
- Flutter仿微信,支付寶密碼輸入框+自定義鍵盤Flutter密碼
- Android 超高仿微信圖片選擇器 圖片該這麼載入Android
- 仿 “即刻APP” 滑動返回的效果APP
- input 輸入框只能輸入數字
- 從一次輸入框無法輸入的bug,談如何限制輸入框輸入型別型別
- 實現一個帶浮動標籤的輸入框
- imemode 控制輸入法,控制輸入框的輸入法
- 仿微信評論控制元件封裝控制元件封裝
- iOS開發使用UIKeyInput自定義密碼輸入框iOSUI密碼
- 完美主義:實現iOS輸入框自動移動iOS
- iOS 簡單實現帶圖片的LabeliOS
- flutter 圖片檢視,仿微信Flutter
- 仿SDWebImage多圖片下載Web
- Android 自定義本地圖片載入庫,仿微信相簿Android地圖
- iOS載入WebP格式圖片小結iOSWeb
- Input 輸入框中 只能輸入正整數
- flutter TextField 輸入框元件Flutter元件
- 自定義UITextView輸入框UITextView
- 輸入框過濾操作
- input只能輸入文字框