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 {
  [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 首行缩进 撤销输入 反撤销输入的实现代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • iOS中的UITextView文字输入光标使用技巧小结

    1.创建并初始化 @property (nonatomic, strong) UITextView *textView; // 创建 self.textView = [[UITextView alloc] initWithFrame:self.view.frame]; // 设置textview里面的字体颜色 self.textView.textColor = [UIColor blackColor]; // 设置字体名字和字体大小 self.textView.font = [UIFont fo

  • IOS 中UITextField,UITextView,UILabel 根据内容来计算高度

    IOS 中UITextField,UITextView,UILabel 根据内容来计算高度 在开发的过程中,常常遇到根据内容来决定控件的高度的情况,常见的就是UITextField,UITextView,UILabel这三个控件,下面一UITextView 为例来说明一下: 首先新新建一个textView. 设施text,font UITextView *textView = [[UITextView alloc] init]; textView.text = @"2015-01-19 14:0

  • iOS UITextField、UITextView只限输入中文、英文、数字及实时限制字符个数的封装实现代码

    引言需求:(输入框限制输入多少字符) 1.一个字母.符号.数字相当于一个字符 2.一个汉字相当于两个字符 3.不能输入特殊字符 4.不能输入emoji表情 直接上代码 一.注册通知 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldChange:) name:UITextFieldTextDidChangeNotification object:nil]; [[NSNotifica

  • IOS 开发UITextView回收或关闭键盘

    IOS 开发UITextView回收或关闭键盘 iOS开发中,发现UITextView没有像UITextField中textFieldShouldReturn:这样的方法,那么要实现UITextView关闭键盘,就必须使用其他的方法,下面是可以使用的几种方法. 1.如果你程序是有导航条的,可以在导航条上面加多一个Done的按钮,用来退出键盘,当然要先实UITextViewDelegate. - (void)textViewDidBeginEditing:(UITextView *)textVie

  • iOS应用开发中的文字选中操作控件UITextView用法讲解

    1.创建并初始化 创建UITextView的文件,并在.h文件中写入如下代码: 复制代码 代码如下: #import <UIKit/UIKit.h>        @interface TextViewController : UIViewController <UITextViewDelegate>    {                  UITextView *textView;    }        @property (nonatomic, retain) UITex

  • iOS开发中Swift3 监听UITextView文字改变的方法(三种方法)

    在项目中使用文本输入框出UITextField之外还会经常使用 UITextView ,难免会有需求监听UITextView文本框内文本数量.下面介绍在swift3中两种常用方式 方式一: 全局通知 1.注册通知 在合适位置注册监听UITextView文本变化的全局通知 //UITextView 监听开始输入的两种方法 //方法一:通知 NotificationCenter.default.addObserver(self, selector: #selector(ComposeVC.textV

  • IOS 中UITextField和UITextView中字符串为空和空格的解决办法

    IOS 中UITextField和UITextView中字符串为空和空格的解决办法 在用UITextField,UITextView声明的属性写一些页面的时候,经常会出现这样的小bug,就是给空值或空格也能进行传值或存储,这里给一些解决的小方法: eg: 这里声明了一个属性,就以此为例来说 @property (nonatomic, strong) UITextField *titlefield; 为空时: if(_titlefield.text == nil){ //执行一些警告操作 } if

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

    最近公司涉及到作家助手的功能,能撤销输入的文字,并能反撤销被撤销掉的文字. 该功能类似ios系统的摇一摇撤销输入. 当时也特迷茫,不知道从何下手,后来搜索了大量的资料,终于完成了这个功能,现在就将该功能的实现写出来,共勉. 这个功能涉及到ios原生类:NSUndomanager.这个类挺强大.废话不多说,直接上代码. #import "ViewController.h" @interface ViewController ()<UITextViewDelegate>{ UI

  • Android设置TextView首行缩进示例代码

    下面是我总结的两种方式,有需要的可以参考借鉴下. 第一种:傻瓜式,空格充当(8个空格占两个汉字的大小). textView.setText(" 设置首行缩进设置首行缩进设置首行缩进设置首行缩进设置首行缩进设置首行缩进设置首行缩进设置首行缩进设置首行缩进设置首行缩进设置首行缩进设置首行缩进设置首行缩进设置首行缩进设置首行缩进设置首行缩进"); 第二种:转义字符. textView.setText("\u3000\u3000" + "设置首行缩进设置首行缩进设

  • Android画板开发之撤销反撤销功能

    一.分析 这篇将会讲解撤销反撤销功能的实现,先讨论一下这个原理是怎么样实现的. 每次撤回的内容,内容是怎么定义呢? 其实就是每一笔,每一笔作为撤回的内容,那每一笔怎么算呢,就是算手指从按下-移动-放开这一个过程就是一笔. 我们只需记录这个过程为一笔,然后用一个已画列表list列表来记录这个过程的paint画笔和路径path. 撤销的时候就把后面的一个数据移到另一个撤销列表 反撤销的时候,就把撤销列表的最后面那条数据移动到已画列表. 然后,还有一个重点,就是画笔的保存数量,上面说记录每一笔画笔,这

  • BAT批量去除文件首行以及批量合并文件脚本

    bat批量去除文件首行 复制代码 代码如下: set n=1 :starline for %%j in (*.txt) do ( :3 if exist D:\work\test\new_%n%.txt (set /a n+=1&goto 3) set file=%n%.txt for /f "skip=1 delims=" %%i in ('type "%file%"') do ( echo %%i >>D:\work\test\new_%n%

  • perl跳过首行读取文件的实现代码

    复制代码 代码如下: #!/usr/bin/perlopen( READ, "<$file" );readline READ; # skip the first linewhile (<READ>) {my ( $id, $axis1, $axis2, $axis3, $value ) = split / /;$line = sprintf ( "%d %d %d %d %d %d",$id, $axis1, $axis2, $axis3, $va

  • 关于iOS自适应cell行高的那些事儿

    前言 其实早就准备写这篇文章了,但是一直没有系统去整理一下相关的demo,加上最近离职了,各种事情忙的有点郁闷,所以一直拖沓了下来.回家休息了一段时间想起来写了一半的demo,在还没找工作的这段空挡时间抽空完善了一下再写篇说明文档备忘一下. 需求背景 iOS的cell行高自适应是个非常常见的需求,也是一个非常简单的需求,之前我遇到过很多小伙伴不知道怎么来实现,在这里就一步步的来分析一下,供大家参考. 问题分析 其他的实现场景就不说了,我们现在来分析一下具体的需求,如图所示: 其实主要实现这几点就

  • iOS UITextView 实现类似微博的话题、提及用户效果

    目录 #话题# 1.高亮 2.点击事件 @提及用户 1.高亮 2.整体删除 最近接了一个需求,在发布动态的时候,增加类似微博的#话题#.@提及用户的效果,在此做一简要记录. #话题# 最终效果是: 编辑过程中#话题内容#实时高亮 高亮部分可以响应点击事件 1.高亮 基本思路是:使用正则匹配出成对的#,再利用UITextView的富文本实现高亮效果. func refreshTopicStyle() { let regex = try! NSRegularExpression(pattern: "

  • javascript实现Emrips反质数枚举的示例代码

    今天看到一个kata,提出一个"emirps"的概念:一个质数倒转后得到的是一个不同的质数,这个数叫做"emirps". 例如:13,17是质数,31,71也是质数,13和17是"emirps". 但是质数757,787,797是回文质数,这意味着反转的数字与原始数字相同,所以它们不被认为是"emirps". 题目要求写一个函数输入一个正整数n,返回小于n的"emirps"的个数,其中最大"emi

  • iOS中navigationController 去掉背景图片、去掉底部线条的核心代码

    废话不多说了,直接给大家贴iOS中navigationController 去掉背景图片.去掉底部线条的核心代码,关键代码如下所示: //去掉背景图片 复制代码 代码如下: [self.navigationController.navigationBar setBackgroundImage:[[UIImage alloc] init] forBarMetrics:UIBarMetricsDefault]; //去掉底部线条 复制代码 代码如下: [self.navigationControll

  • 解决html input验证只能输入数字,不能输入其他的问题

    此方法为借鉴别人的,在此只做记录.希望对大家也有用. <input type="text" onkeyup="if(!/^\d+$/.test(this.value)) tip.innerHTML='必须输入数字,且不能有空格.'; else tip.innerHTML='';" /><span id="tip"></span> 以上这篇解决html input验证只能输入数字,不能输入其他的问题就是小编分享给

随机推荐