欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2023-12-18 14:47:34
 最近公司涉及到作家助手的功能,能撤销输入的文字,并能反撤销被撤销掉的文字。 该功能类似ios系统的摇一摇撤销输入。 当时也特迷茫,不知道从何下手,后来搜索了...

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

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

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

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

#import "viewcontroller.h"
@interface viewcontroller ()<uitextviewdelegate>{
  uitextview *_textview;
  nsundomanager *_undomanager;
  nsinteger _length;
  uibutton *undobutton;
  uibutton *redobutton;
}
@end
@implementation viewcontroller
- (void)viewdidload {
  [super viewdidload];
  uibarbuttonitem *undoitem = [[uibarbuttonitem alloc]initwithbarbuttonsystemitem:uibarbuttonsystemitemundo target:self action:@selector(undoitem)];
  uibarbuttonitem *redoitem = [[uibarbuttonitem alloc]initwithbarbuttonsystemitem:uibarbuttonsystemitemredo target:self action:@selector(redoitem)];
  self.navigationitem.leftbarbuttonitem = undoitem;
  self.navigationitem.rightbarbuttonitem = redoitem;
  [[nsnotificationcenter defaultcenter] addobserver:self selector:@selector(keyboardshow:) name:uikeyboardwillshownotification object:nil];
  [[nsnotificationcenter defaultcenter] addobserver:self selector:@selector(keyboardhidden:) name:uikeyboardwillhidenotification object:nil];
  _length = 0;
//初始化nsundomanager
  _undomanager = [[nsundomanager alloc] init];
  _textview = [[uitextview alloc]initwithframe:cgrectmake(0, 200, self.view.frame.size.width, 400)];
  _textview.backgroundcolor = [uicolor yellowcolor];
  _textview.delegate = self;
  _textview.font = [uifont systemfontofsize:15];
  _textview.layer.cornerradius = 5;
  _textview.layer.maskstobounds = yes;
  _textview.textcolor = [uicolor blackcolor];
  _textview.text = @" ";//要设置初始文本,不然段落体现不出来。
  nsmutableparagraphstyle *paragraphstyle = [[nsmutableparagraphstyle alloc] init];
  paragraphstyle.linespacing = 5;  //行间距
  paragraphstyle.firstlineheadindent = 30;  /**首行缩进宽度*/
  paragraphstyle.alignment = nstextalignmentleft;
  nsdictionary *attributes = @{
                 nsfontattributename:[uifont systemfontofsize:13],
                 nsparagraphstyleattributename:paragraphstyle
                 };
  _textview.attributedtext = [[nsattributedstring alloc] initwithstring:_textview.text attributes:attributes];
//监听textview文本改动的通知
 [[nsnotificationcenter defaultcenter]addobserver:self selector:@selector(changetextviewtext) name:uitextviewtextdidchangenotification object:nil];
  [self.view addsubview:_textview];
}
-(void)redoitem{
  //反撤销
  [_undomanager redo];
}
-(void)undoitem{
  //撤销
  [_undomanager undo];
}
-(void)keyboardshow:(nsnotification *)noti{
  nsdictionary *dic = noti.userinfo;
  nsvalue *avalue = [dic objectforkey:uikeyboardframeenduserinfokey];
  cgrect keyboardrect = [avalue cgrectvalue];
  int height = keyboardrect.size.height;
  [_textview setcontentinset:uiedgeinsetsmake(0, 0, height, 0)];
}
-(void)keyboardhidden:(nsnotification *)noti{
  [_textview setcontentinset:uiedgeinsetsmake(0, 0, 0, 0)];
}
- (void)setmyobjecttitle:(nsstring *)newtitle{
  //判断当前nsundomanager的状态,是处于撤销或者反撤销的状态
-(void)textviewdidchange:(uitextview *)textview
  if (_undomanager.isundoing) {
    nsinteger length = newtitle.length;
    if (_textview.text.length>0) {
      //获取 
      _textview.text = [_textview.text substringwithrange:nsmakerange(0, _textview.text.length - length)];
      [_undomanager registerundowithtarget:self
                    selector:@selector(setmyobjecttitle:)
                     object:newtitle];
    }
  }else if (_undomanager.isredoing){
    _textview.text = [_textview.text stringbyappendingstring:newtitle];
    [_undomanager registerundowithtarget:self
                  selector:@selector(setmyobjecttitle:)
                   object:newtitle];
  }else{
    nsstring *currenttext = _textview.text;
    if (newtitle != currenttext) {
      _textview.text = currenttext;
      [_undomanager registerundowithtarget: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 = [nsstring stringwithformat:@"%@",[_textview.text substringwithrange:nsmakerange(_length, newlength)]];
    }else{
      text = _textview.text;
    }
  }else{
    text = _textview.text;
  }
  _length = _textview.text.length;
  [self setmyobjecttitle:text];
}

总结

以上所述是小编给大家介绍的ios uitextview 首行缩进 撤销输入 反撤销输入的实现代码,希望对大家有所帮助

上一篇:

下一篇: