iOS UITextView 首行缩进 撤销输入 反撤销输入的实现

最近公司涉及到作家助手的功能,能撤销输入的文字,并能反撤销被撤销掉的文字。

该功能类似ios系统的摇一摇撤销输入。

当时也特迷茫,不知道从何下手,后来搜索了大量的资料,终于完成了这个功能,现在就将该功能的实现写出来,共勉。

这个功能涉及到ios原生类:NSUndomanager。这个类挺强大。废话不多说,直接上代码。

#import "ViewController.h"

@interface ViewController ()<UITextViewDelegate>{

    

    UITextView *_textView;


    NSUndoManager *_undomanager;

    

    NSInteger _length;

    

    UIButton *undobutton;

    

    UIButton *redobutton;

    

}


@end


@implementation ViewController


- (void)viewDidLoad {

    [superviewDidLoad];

    

    UIBarButtonItem *undoItem = [[UIBarButtonItemalloc]initWithBarButtonSystemItem:UIBarButtonSystemItemUndotarget:selfaction:@selector(undoitem)];

    

    UIBarButtonItem *redoItem = [[UIBarButtonItemalloc]initWithBarButtonSystemItem:UIBarButtonSystemItemRedotarget:selfaction:@selector(redoitem)];

    

    self.navigationItem.leftBarButtonItem = undoItem;

    

    self.navigationItem.rightBarButtonItem = redoItem;

    [[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(keyBoardShow:)name:UIKeyboardWillShowNotificationobject:nil];

    

    [[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(keyBoardHidden:)name:UIKeyboardWillHideNotificationobject:nil];

    

    _length =0;

    

//初始化NSUndoManager

    _undomanager = [[NSUndoManageralloc] init];


    _textView = [[UITextViewalloc]initWithFrame:CGRectMake(0,200, self.view.frame.size.width,400)];

    

    _textView.backgroundColor = [UIColoryellowColor];

    _textView.delegate =self;

    _textView.font = [UIFontsystemFontOfSize:15];

    _textView.layer.cornerRadius =5;

    _textView.layer.masksToBounds =YES;

    _textView.textColor = [UIColorblackColor];

    _textView.text =@"  ";//要设置初始文本,不然段落体现不出来。

    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStylealloc] init];

    paragraphStyle.lineSpacing =5;    //行间距

    paragraphStyle.firstLineHeadIndent =30;    /**首行缩进宽度*/

    paragraphStyle.alignment =NSTextAlignmentLeft;

    NSDictionary *attributes =@{

                                 NSFontAttributeName:[UIFontsystemFontOfSize:13],

                                 NSParagraphStyleAttributeName:paragraphStyle

                                 };

    _textView.attributedText = [[NSAttributedStringalloc] initWithString:_textView.textattributes:attributes];

    

//监听textview文本改动的通知

   

 [[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(changeTextViewText)name:UITextViewTextDidChangeNotificationobject:nil];

  

    [self.viewaddSubview:_textView];

}

-(void)redoitem{

    //反撤销

    [_undomanagerredo];


}

-(void)undoitem{

    //撤销

    [_undomanagerundo];


}


-(void)keyBoardShow:(NSNotification *)noti{

    

    NSDictionary *dic = noti.userInfo;

    

    NSValue *aValue = [dicobjectForKey:UIKeyboardFrameEndUserInfoKey];

    

    CGRect keyboardRect = [aValueCGRectValue];

    

    int height = keyboardRect.size.height;

    

    [_textViewsetContentInset:UIEdgeInsetsMake(0,0, height, 0)];

}


-(void)keyBoardHidden:(NSNotification *)noti{

    

    

    [_textViewsetContentInset:UIEdgeInsetsMake(0,0, 0,0)];

    

}

- (void)setMyObjectTitle:(NSString *)newTitle{

    //判断当前NSUndoManager的状态,是处于撤销或者反撤销的状态

    if (_undomanager.isUndoing) {

        

        NSInteger length = newTitle.length;

       

        if (_textView.text.length>0) {

           //获取 

            _textView.text = [_textView.textsubstringWithRange:NSMakeRange(0,_textView.text.length - length)];

            

            [_undomanagerregisterUndoWithTarget:self

                                        selector:@selector(setMyObjectTitle:)

                                          object:newTitle];


        }

        

        

    }elseif (_undomanager.isRedoing){

        

        _textView.text = [_textView.textstringByAppendingString:newTitle];

        

        [_undomanagerregisterUndoWithTarget:self

                                    selector:@selector(setMyObjectTitle:)

                                      object:newTitle];

        

    }else{

        

        NSString *currentText =_textView.text;

        

        if (newTitle != currentText) {

            

            _textView.text = currentText;

            

            [_undomanagerregisterUndoWithTarget:self

                                        selector:@selector(setMyObjectTitle:)

                                          object:newTitle];

            

        }else{

            

            _textView.text = newTitle;

            

        }

    }

    

}


-(void)changeTextViewText{

    

    if (_textView.text.length>0) {

        

        undobutton.enabled =YES;

    }else{

        

        undobutton.enabled =NO;

        

        redobutton.enabled =NO;



    }

    NSString *text ;


    if (_length !=0) {

        

        NSInteger textLength =_textView.text.length;

        

       

        if (textLength >_length) {

            

            NSInteger newLength = textLength -_length;


            text = [NSStringstringWithFormat:@"%@",[_textView.textsubstringWithRange:NSMakeRange(_length, newLength)]];

       

        }else{

            

            

            text = _textView.text;

            

        }

        

    }else{

        

        text = _textView.text;

 

    }

   

    _length =_textView.text.length;

    

    [selfsetMyObjectTitle:text];


    

}


你可能感兴趣的:(iOS UITextView 首行缩进 撤销输入 反撤销输入的实现)