Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save keicoder/9597222 to your computer and use it in GitHub Desktop.
Save keicoder/9597222 to your computer and use it in GitHub Desktop.
objective-c : making UITextView programmatically with custom class and UITextViewDelegate (JTextView)
//making UITextView programmatically with custom class and UITextViewDelegate (JTextView)
//1. make basic UITextView programmatically with custom class
//Prefix header
#ifdef __OBJC__
#define debug 1
#define kSTATUSBAR_OFFSET 20.0 // 스테이터스 바 높이
#define kINSET_TOP 10.0 // 텍스트 뷰 인셋 top
#define kINSET_LEFT 10.0 // 텍스트 뷰 인셋 left
#define kINSET_BOTTOM 10.0 // 텍스트 뷰 인셋 bottom
#define kINSET_RIGHT 10.0 // 텍스트 뷰 인셋 right
#endif
//JTextView.h
@interface JTextView : UITextView
- (void)updateNoteTextViewFrame;
- (void)keyboardDidShow:(NSNotification *)notification;
- (void)keyboardWillHide:(NSNotification*)notification;
@end
//JTextView.m
@implementation JTextView
{
CGRect _applicationFrame;
CGSize _keyboardSize; //width, height
}
#pragma mark - Class methods
//in case making JTextView in code
- (id)initWithFrame:(CGRect)frame
{
if (debug==1) {NSLog(@"Running %@ '%@'", self.class, NSStringFromSelector(_cmd));}
self = [super initWithFrame:frame];
if (self)
{
}
return self;
}
+ (void)initialize
{
if (self == [JTextView class])
[self conformsToProtocol:@protocol(UITextInput)];
}
// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardDidShow:(NSNotification *)notification
{
if (debug==1) {NSLog(@"Running %@ '%@'", self.class, NSStringFromSelector(_cmd));}
//키보드 사이즈 인스턴스 변수에 저장
NSDictionary *userInfo = [notification userInfo];
_keyboardSize = [[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
// NSLog(@"_keyboardSize: %f, %f", _keyboardSize.width, _keyboardSize.height);
// CGPoint _keyboardOrigin = [[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].origin;
// NSLog(@"_keyboardOrigin: %f, %f", _keyboardOrigin.x, _keyboardOrigin.y);
// [self updateNoteTextViewFrame];
[self updateNoteTextViewInset];
}
// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillHide:(NSNotification*)notification
{
if (debug==1) {NSLog(@"Running %@ '%@'", self.class, NSStringFromSelector(_cmd));}
// [self updateNoteTextViewFrameInCaseDown];
[self updateNoteTextViewInsetInCaseDown];
}
//텍스트 뷰의 인셋 사이즈 변경
- (void)updateNoteTextViewInset
{
if (debug==1) {NSLog(@"Running %@ '%@'", self.class, NSStringFromSelector(_cmd));}
// Step 1: Adjust the bottom content inset of your scroll view by the keyboard height.
UIEdgeInsets contentInset = self.contentInset;
contentInset.bottom = _keyboardSize.height;
self.contentInset = contentInset;
}
- (void)updateNoteTextViewInsetInCaseDown
{
if (debug==1) {NSLog(@"Running %@ '%@'", self.class, NSStringFromSelector(_cmd));}
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
self.contentInset = contentInsets;
self.scrollIndicatorInsets = contentInsets;
}
//텍스트 뷰의 프레임 사이즈 변경
- (void)updateNoteTextViewFrame
{
self.frame = CGRectMake(0, kSTATUSBAR_OFFSET, _applicationFrame.size.width, _applicationFrame.size.height - _keyboardSize.height); //kSTATUSBAR_OFFSET: 20
}
- (void)updateNoteTextViewFrameInCaseDown
{
_keyboardSize = CGSizeMake(0.0, 0.0);
[UIView animateWithDuration:0.3 animations:^{
[self updateNoteTextViewFrame];
}];
}
@end
//AppDelegate.h
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end
//AppDelegate.m
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
return YES;
}
@end
//NoteViewController.h
@interface NoteViewController : UIViewController
@end
//NoteViewController.m
#import "JTextView.h"
@interface NoteViewController () <UITextViewDelegate>
@end
@implementation NoteViewController
{
JTextView *_textView;
CGRect _applicationFrame;
}
- (void)loadView
{
if (debug==1) {NSLog(@"Running %@ '%@'", self.class, NSStringFromSelector(_cmd));}
_applicationFrame = [[UIScreen mainScreen] applicationFrame]; //Frame: : 0, 20, 320, 548
//텍스트 뷰 생성
_textView = [[JTextView alloc] initWithFrame:CGRectMake(0.0, kSTATUSBAR_OFFSET, _applicationFrame.size.width, _applicationFrame.size.height)]; //Frame: 0, 20, 320, 548, kSTATUSBAR_OFFSET: 20
// CGRect textViewFrame = _textView.frame;
// NSLog (@"textViewFrame: %f, %f, %f, %f", textViewFrame.origin.x, textViewFrame.origin.y, textViewFrame.size.width, textViewFrame.size.height);
//텍스트 뷰 속성
_textView.font = [UIFont systemFontOfSize:14]; //텍스트 뷰 폰트
_textView.backgroundColor = [UIColor colorWithRed:0.95 green:0.95 blue:0.93 alpha:1];
_textView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;
[_textView setTextContainerInset:UIEdgeInsetsMake(kINSET_TOP, kINSET_LEFT, kINSET_BOTTOM, kINSET_RIGHT)]; //텍스트 뷰 인셋 iOS 7
CALayer *imageLayer = _textView.layer;
[imageLayer setCornerRadius:10];
_textView.delegate = self;
//컨테이너 뷰 생성
UIView *containerView = [[UIView alloc] initWithFrame:_applicationFrame];
[containerView addSubview:_textView];
//뷰 속성
self.view = containerView;
self.view.backgroundColor = [UIColor colorWithRed:0.99 green:0.4 blue:0.43 alpha:1];
}
#pragma mark - View Life Cycle
- (void)viewDidLoad
{
[super viewDidLoad];
//더미 텍스트 파일 불러오기
NSError *error;
NSString* path = [[NSBundle mainBundle] pathForResource:@"dummyText" ofType:@"txt"];
NSString* content = [NSString stringWithContentsOfFile:path
encoding:NSUTF8StringEncoding
error:&error];
_textView.text = content;
[self registerForKeyboardNotifications];
}
- (void)viewWillDisappear:(BOOL)animated
{
if (debug==1) {NSLog(@"Running %@ '%@'", self.class, NSStringFromSelector(_cmd));}
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self]; //키보드 옵저버 해제
}
#pragma mark - Keyboard Notifications
// Call this method somewhere in your view controller setup code.
- (void)registerForKeyboardNotifications
{
//키보드 팝업 옵저버 (키보드 팝업 시 텍스트 뷰 사이즈 조절)
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification object:self.view.window];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification object:self.view.window];
}
// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardDidShow:(NSNotification *)notification
{
if (debug==1) {NSLog(@"Running %@ '%@'", self.class, NSStringFromSelector(_cmd));}
[_textView keyboardDidShow:notification];
[self moveTextToCaretPosition:_textView withAnimation:YES];
}
// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillHide:(NSNotification*)notification
{
if (debug==1) {NSLog(@"Running %@ '%@'", self.class, NSStringFromSelector(_cmd));}
[_textView keyboardWillHide:notification];
}
#pragma mark - UITextView delegate method (optional)
- (void)textViewDidBeginEditing:(UITextView *)textView
{
_textView.backgroundColor = [UIColor colorWithRed:0.68 green:0.85 blue:0.94 alpha:1];
}
- (void)textViewDidEndEditing:(UITextView *)textView
{
_textView.backgroundColor = [UIColor colorWithRed:0.95 green:0.95 blue:0.93 alpha:1];
}
#pragma mark UITextView change selection, text
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
return YES;
}
- (void)textViewDidChangeSelection:(UITextView *)textView
{
}
- (void)textViewDidChange:(UITextView *)textView
{
// if (debug==1) {NSLog(@"Running %@ '%@'", self.class, NSStringFromSelector(_cmd));}
[self moveTextToCaretPosition:textView withAnimation:YES];
}
- (void)moveTextToCaretPosition:(UITextView *)textView withAnimation:(BOOL)shouldAnimate
{
// where the blinky caret is
CGRect caretRect = [textView caretRectForPosition:textView.selectedTextRange.start];
CGFloat offscreen = caretRect.origin.y + caretRect.size.height - (textView.contentOffset.y + textView.bounds.size.height - textView.contentInset.bottom - textView.contentInset.top);
CGPoint offsetP = textView.contentOffset;
offsetP.y += offscreen + 1; // 3 px -- margin puts caret 3 px above bottom
if (offsetP.y >= 0) {
if (shouldAnimate) {
[UIView animateWithDuration:0.3 animations:^{
[textView setContentOffset:offsetP];
}];
}
else {
[textView setContentOffset:offsetP];
}
}
}
#pragma mark - Memory Warning
- (void)didReceiveMemoryWarning
{
if (debug==1) {NSLog(@"Running %@ '%@'", self.class, NSStringFromSelector(_cmd));}
[super didReceiveMemoryWarning];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment