swift html编辑器,干货|swift,富文本编辑器

这一篇我们将实现一个富文本编辑器,拥有功能:

1、斜体、下划线混排。

2、图文混排

3、字体大小。

4、选择自定义字体。

5、制作长图片分享到微信朋友圈与微信好友。

6、调用系统邮件发送文本。

先来看一下大体的效果吧,还有一些效果将在后面演示:

(写在最前面,这个Demo存在大量BUG,我只是通过他来演示一些功能,也许在后面我会做一个完整的APP,到时候也会再来写一遍,来说说一些BUG如何处理)。

76565693_1

1.png

富文本编辑器在以前需要使用CoreText来实现,但是不得不说这真的是一个不小的工程,但是在iOS7发布以后,apple发布了TextKit,通过TextKit我们能够轻松实现很多从前难以实现的功能。

1、斜体、下划线混排、字体的增大以及减小

在SB中拖入一个UITextView,此后的所有操作都是对这个TextView中的文字进行操作,先来看几行代码:

var string = NSMutableAttributedString(attributedString: self.textview.attributedText)

string.addAttribute(NSObliquenessAttributeName, value: 0.5, range: NSMakeRange(0,5))

我们来解释一下这一段代码:

首先,我们从TextView中获取了string,这个string是NSMutableAttributedString类型的,这个类型继承自String,但是呢,从名字上我们就可以看出来这个类型,我们可以给字符串添加不同的属性,我们回到代码。这段代码的第二句我们通过:

func addAttribute(name: String, value: AnyObject, range: NSRange)

这个函数给字符串添加了属性,这个API的第1、2个参数就是确定添加的属性类型,在这里我们添加的就是斜体这个属性,斜体这个属性的Value参数填写0~1之间的数值,在这个我们填写的是0.5.来看第二个参数,第二个参数是添加属性的范围,填写的是一个NSRange类型的值,应该不难理解。

以上代码段的功能就是给textview的字符串的第0个字符开始,连续五个字符添加斜体的效果。

是不是十分方便?~~~~~是的。

以上内容只是为了演示UITextView中的attributedText属性,事实上我们不需要这么做(感谢刘大大,告诉我接下来这种做法)。

在TextView中有一个属性叫做typingAttributes,xcode对这个属性的解释是这样的automatically resets when the selection changes,意思就是我们对这个属性进行设置可以改变接下来改变的文字。

也许这样说,不能让人太好的理解,我们在按钮中添加以下代码

@IBAction func Obliqueness(sender: AnyObject) {

textview.typingAttributes[NSObliquenessAttributeName] = (textview.typingAttributes[NSObliquenessAttributeName] as? NSNumber) == 0 ? 0.5 : 0

}

当NSObliquenessAttributeName的值为0时,点击按钮将将之改变为1,为1时则相反。我们点一下试试,神奇的事情发生啦啦啦啦~~~接下来我们输入的文字都变成了斜体。再次点击则变回正常。

以此类推,我们写出下划线、字体的增大以及减小的代码。

/**

字体减小

:param: sender

*/

@IBAction func fontincrease(sender: AnyObject) {

self.fontSize -= 2

self.textview.typingAttributes[NSFontAttributeName] = UIFont.systemFontOfSize((CGFloat)(self.fontSize))

}

/**

字体增大

:param: sender

*/

@IBAction func fontdecase(sender: AnyObject) {

self.fontSize += 2

self.textview.typingAttributes[NSFontAttributeName] = UIFont.systemFontOfSize((CGFloat)(self.fontSize))

}

/**

设置斜体

:param: sender

*/

@IBAction func Obliqueness(sender: AnyObject) {

textview.typingAttributes[NSObliquenessAttributeName] = (textview.typingAttributes[NSObliquenessAttributeName] as? NSNumber) == 0 ? 0.5 : 0

}

/**

设置下划线

:param: sender

*/

@IBAction func underline(sender: AnyObject) {

self.textview.typingAttributes[NSUnderlineStyleAttributeName] = (NSUnderlineStyle.StyleSingle.hashValue ) == 0 ? 1 : NSUnderlineStyle.StyleSingle.hashValue

}

/**

实现方法都是类似的,十分方便的已经实现了很多功能,这放在以前是不可能的(其实我不知道以前实现究竟有多复杂——!)。

2、插入图片。

前面我们知道TextView存在一个属性叫做attributedText,插入图片需要做的就是在TextView的这个属性中添加图片,上代码。

//1

var string = NSMutableAttributedString(attributedString: self.textview.attributedText)

//2

var textAttachment = NSTextAttachment()

textAttachment.image = img

//3

var textAttachmentString = NSAttributedString(attachment: textAttachment)

var countString:Int = count(self.textview.text) as Int

string.insertAttributedString(textAttachmentString, atIndex: countString)

//4

textview.attributedText = string

>

- 1、获取当前的attributedString

- 2、新建一个NSTextAttachment,设置他的图片属性

- 3、将刚刚创建的NSTextAttachment,添加在原本的attributedString的最后面

- 4、重定义** textview.attributedText **

以上代码中出现一个变量img,这个变量就是从系统相册获取图片,代码如下:

@IBAction func photeSelect(sender: AnyObject) {

var sheet:UIActionSheet

if(UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera)){

sheet = UIActionSheet(title: nil, delegate: self, cancelButtonTitle: "取消", destructiveButtonTitle: nil, otherButtonTitles: "从相册选择", "拍照")

}else{

sheet = UIActionSheet(title:nil, delegate: self, cancelButtonTitle: "取消", destructiveButtonTitle: nil, otherButtonTitles: "从相册选择")

}

sheet.showInView(self.view)

}

func actionSheet(actionSheet: UIActionSheet, clickedButtonAtIndex buttonIndex: Int) {

var sourceType = UIImagePickerControllerSourceType.PhotoLibrary

if(buttonIndex != 0){

if(buttonIndex==1){ //相册

sourceType = UIImagePickerControllerSourceType.PhotoLibrary

}else{

sourceType = UIImagePickerControllerSourceType.Camera

}

let imagePickerController:UIImagePickerController = UIImagePickerController()

imagePickerController.delegate = self

imagePickerController.allowsEditing = true//true为拍照、选择完进入图片编辑模式

imagePickerController.sourceType = sourceType

self.presentViewController(imagePickerController, animated: true, completion: {

})

}

}

首先是弹出一个alertView,让你进行选择,选择以后,将调用下面的方法,进入到相册进行选择图片。在这里你需要继承几个协议,不然在选择以后不会触发下面的方法:UIActionSheetDelegate,UIImagePickerControllerDelegate。同时进入相册你需要添加几个库:AssetsLibrary.framework和MobileCoreServices.framework。具体代码解释在这里就不行进解释,今天我们把重点放在富文本的实现上。当你选择图片以后,将促发以下方法,这也是前面添加的协议的功能。

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]){ var string = NSMutableAttributedString(attributedString: self.textview.attributedText) var img = info[UIImagePickerControllerEditedImage] as! UIImage img = self.scaleImage(img)

var textAttachment = NSTextAttachment()

textAttachment.image = img

var textAttachmentString = NSAttributedString(attachment: textAttachment)

var countString:Int = count(self.textview.text) as Int

string.insertAttributedString(textAttachmentString, atIndex: countString)

textview.attributedText = string

self.textview.becomeFirstResponder()

picker.dismissViewControllerAnimated(true, completion: nil)

}

同时在这个函数中我们给文本插入图片,插入方法在前面已经说过了。

当我们选择图片以后你会发现由于图片太大,所以在界面上只能显示一部分,那么我们就需要压缩图片,压缩方法如下:

func scaleImage(image:UIImage)->UIImage{

UIGraphicsBeginImageContext(CGSizeMake(self.view.bounds.size.width, image.size.height*(self.view.bounds.size.width/image.size.width)))

image.drawInRect(CGRectMake(0, 0, self.view.bounds.size.width, image.size.height*(self.view.bounds.size.width/image.size.width)))

var scaledimage = UIGraphicsGetImageFromCurrentImageContext()

UIGraphicsEndImageContext()

return scaled image

}

这个方法将图片的宽度设置为屏幕的宽度,高度按比例缩放。

好的~~~~~我们终于实现了插入图片,其实在这里有一个很大的问题,就是下面这句话:

textview.attributedText = string

我们每次插入图片都将TextView的内容全部改变了一次,这样的做法,先不提在大量文字的情况下可能造成的卡顿问题,同时造成了编排问题,有同学可能已经发现了,当我们用这样的方法插入图片以后,当我们再次改变属性的时候,视图将会瞬间调到最上面,原因就是这句话。至于如何解决~~~~还没想到——!

3、选择字体

改变字体的方法其实和我们设置斜体,下划线等是一样的,方法如下:

func lovefont(sender:AnyObject){

self.textview.typingAttributes[NSFontAttributeName] = UIFont(name: "1-", size: (CGFloat)(self.fontSize))

}

那么我们现在的问题就是自定义字体了,毕竟xcode的字体大多不支持中文,同时中文显示的时候不那么优雅,我们要说的就是自定义字体。

加载自定义字体,并不是太过复杂,我在简书看到这篇文章描述加载自定义字体就感觉写的很好,http://www.jianshu.com/p/d728570bdf7b 小伙伴们有兴趣的话自行跳转过去看吧,这里就不重复介绍了。

**4、制作长图片分享到微信朋友圈与微信好友。**

那么我们需要做的第一步就是制作长图片,代码如下:

func madelongPicture() -> UIImage {

var image : UIImage!

UIGraphicsBeginImageContext(self.textview.contentSize)

var savedContentOffset = self.textview.contentOffset

var savedFrame = self.textview.frame

self.textview.contentOffset = CGPointZero

self.textview.frame = CGRectMake(0, 0, self.textview.contentSize.width, self.textview.contentSize.height)

self.textview.layer.renderInContext(UIGraphicsGetCurrentContext())

image = UIGraphicsGetImageFromCurrentImageContext()

self.textview.contentOffset = savedContentOffset

self.textview.frame = savedFrame

UIGraphicsEndPDFContext()

return image

}

TextView继承自ScorllView,所以我们只需要给TextView进行截图,就可以制作一张长图片了,方法如上。然后我们需要做的就是调用微信给我们的API,将图片分享到朋友圈。

76565693_2

由于分享的话要申请AppId,所以在这里没有实现这个功能,不过实现的方法并不复杂。

其实里头已经讲的很清楚了,有不明白的亲可以留言哦~

5、调用系统邮件发送文本

调用系统邮件,你可以将刚刚写好的文章或者啥的发送给好朋友,或者交给老师检查~~~~~~~首先我们还是得制作长图片,制作方法上面已经讲过了,就不重复累赘了,这里讲一下如何调用系统邮件。

首先你得继承一个协议:MFMailComposeViewControllerDelegate

然后代码如下:

@IBAction func email(sender: AnyObject) {

UIApplication.sharedApplication().keyWindow?.endEditing(true)

var configuredMailComposeViewController = MailComposeViewController()

if canSendMail() {

presentViewController(configuredMailComposeViewController, animated: true, completion: nil)

} else {

showSendMailErrorAlert()

}

}

func MailComposeViewController() -> MFMailComposeViewController {

let mailComposerVC = MFMailComposeViewController()

mailComposerVC.mailComposeDelegate = self

mailComposerVC.setToRecipients(nil)

mailComposerVC.setSubject(nil)

mailComposerVC.setMessageBody(self.textview.text, isHTML: false)

var addPic = self.madelongPicture()

var imageData = UIImagePNGRepresentation(addPic)

mailComposerVC.addAttachmentData(imageData, mimeType: "", fileName: "longPicture.png")

return mailComposerVC

}

func canSendMail() -> Bool {

return MFMailComposeViewController.canSendMail()

}

func mailComposeController(controller: MFMailComposeViewController!, didFinishWithResult result: MFMailComposeResult, error: NSError!) {

controller.dismissViewControllerAnimated(true, completion: nil)

}

func showSendMailErrorAlert() {

let sendMailErrorAlert = UIAlertView(title: "Could Not Send Email", message: "Your device could not send e-mail. Please check e-mail configuration and try again.", delegate: self, cancelButtonTitle: "OK")

sendMailErrorAlert.show()

}

代码就在上面了,自己感受一下的,解释不动了。

效果如下:

76565693_3

1.png

接下来也许会造个轮子,同时解决所有的BUG(至少我能发现的)。

亲们,自己下载代码感受一下,然后喜欢的换请点个喜欢同时关注一下我。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值