TextEditorDemo: A Rich Text Editor Based on swift,
TextEditorDemo
Swift: textEditorDemo a simple Rich Text Editor
A simple Rich Text Editor
(IPhone 5S Xcode 6.3 swift 1.2)
Some basic functions are implemented and solved:
Project address
Github address
If there is an update on Weibo, a message will be sent: My weibo
1. Change the font:
// Change the font size: self. text. typingAttributes [NSFontAttributeName] = UIFont. systemFontOfSize (CGFloat) (self. fontSize) // underline: self. text. typingAttributes [NSUnderlineStyleAttributeName] = 1 // bold: self. text. typingAttributes [NSFontAttributeName] = UIFont. boldSystemFontOfSize (CGFloat) (self. fontSize) // italic: text. typingAttributes [NSObliquenessAttributeName] = 0.5
2. Insert an image:
/* // Select a photo */@ IBAction func photeSelect (sender: AnyObject) {self. text. resignFirstResponder () var sheet: UIActionSheet if (UIImagePickerController. isSourceTypeAvailable (UIImagePickerControllerSourceType. camera) {sheet = UIActionSheet (title: nil, delegate: self, cancelButtonTitle: "cancel", destructiveButtonTitle: nil, otherButtonTitles: "select from album", "")} else {sheet = UIActionSheet (title: nil, delegate: sel F, cancelButtonTitle: "cancel", destructiveButtonTitle: nil, otherButtonTitles: "select from album")} sheet. showInView (self. view)} func actionSheet (actionSheet: UIActionSheet, clickedButtonAtIndex buttonIndex: Int) {var sourceType = UIImagePickerControllerSourceType. photoLibrary if (buttonIndex! = 0) {if (buttonIndex = 1) {// album sourceType = UIImagePickerControllerSourceType. photoLibrary self. text. resignFirstResponder ()} else {sourceType = UIImagePickerControllerSourceType. camera} let imagePickerController: UIImagePickerController = UIImagePickerController () imagePickerController. delegate = self imagePickerController. allowsEditing = true // true indicates taking a photo. After selecting and entering the image editing mode, select imagePickerController. sourceType = SourceType self. presentViewController (imagePickerController, animated: true, completion :{})} func imagePickerController (picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject: AnyObject]) {var string: NSMutableAttributedString string = NSMutableAttributedString (attributedString: self. text. attributedText) var img = info [UIImagePickerControllerEditedImage]! UIImage img = self. scaleImage (img) var textAttachment = NSTextAttachment () textAttachment. image = img var textAttachmentString = NSAttributedString (attachment: textAttachment) var countString: Int = count (self. text. text) as Int string. insertAttributedString (textAttachmentString, atIndex: countString) // you can use this function to insert data to the point where the cursor is located. ps: If you want to share text. attributedText = string/* // string. appendAttributedString (textAttachmentString) 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 scaledimage}
3. Implement keyboard hiding and pop-up
// * // This bool sign is used to make the keyboard appear and hide it in pairs. Otherwise, it will jump out twice. I can only solve this problem in this way. = // ps: If you have a better solution, I hope to share it with you! The preceding contact information is */var bool: Bool = true func handleKeyboardWillShowNotification (notification: NSNotification) {if bool {keyboardWillChangeFrameWithNotification (notification, showsKeyboard: true) println ("--- show ") bool =! Bool} func handleKeyboardWillHideNotification (notification: NSNotification) {if! Bool {keyboardWillChangeFrameWithNotification (notification, showsKeyboard: false) println ("--- hide") bool =! Bool} func keyboardWillChangeFrameWithNotification (notification: NSNotification, showsKeyboard: Bool) {println ("4") let userInfo = notification. userInfo! Let animationDuration: NSTimeInterval = (userInfo [UIKeyboardAnimationDurationUserInfoKey]! NSNumber). doubleValue // Convert the keyboard frame from screen to view coordinates. let keyboardScreenBeginFrame = (userInfo [UIKeyboardFrameBeginUserInfoKey]! NSValue). CGRectValue () let keyboardScreenEndFrame = (userInfo [UIKeyboardFrameEndUserInfoKey]! NSValue ). CGRectValue () let keyboardViewBeginFrame = view. convertRect (keyboardScreenBeginFrame, fromView: view. window) let keyboardViewEndFrame = view. convertRect (keyboardScreenEndFrame, fromView: view. window) var originDelta = abs (keyboardViewEndFrame. origin. y-keyboardViewBeginFrame. origin. y) println ("the origin: \ (originDelta)") // The text view shoshould be adjusted, update the constant for this constraint. if showsKeyboard {textViewBottomLayoutGuideConstraint. constant + = (originDelta) self. toolBarLayOut. constant + = originDelta} else {textViewBottomLayoutGuideConstraint. constant-= (originDelta) self. toolBarLayOut. constant-= originDelta} UIView. animateWithDuration (animationDuration, delay: 0, options :. beginFromCurrentState, animations: {self. view. layoutIfNeeded ()}, completion: nil) // Scroll to the selected text once the keyboard frame changes. self. text. scrollRangeToVisible (self. text. selectedRange) // slide the TextView to the cursor position}
4. Implement the default prompt text effect: the prompt text disappears automatically when you click Edit.
/* // Implement the default prompt text effect: clicking the text will automatically disappear. */Func textViewShouldBeginEditing (textView: UITextView)-> Bool {if! IsThereHavedata {text. text = "" text. textColor = UIColor. blackColor () isThereHavedata = true} return true}
5. fixed the problem of changing the text attribute and automatically slide TextView to the top.
Self. text. layoutManager. allowsNonContiguousLayout = false // used to solve the problem of changing the text attribute. TextView automatically slides to the top ### 6. slide TextView to the cursor's position self. text. scrollRangeToVisible (self. text. selectedRange) #### 7. click the toolbar at the bottom of the button to hide it to the right using the automatic layout.
@ IBAction func toright (sender: UIBarButtonItem) {if self. toRight. constant <0 {// you can easily determine whether to move left or right. toolbar. layer. cornerRadius = 22 // change to the rounded corner self. toRight. constant + = (text. bounds. width-10) sender. image = UIImage (named: "fa-left") // change image} else {self. toolbar. layer. cornerRadius = 0 // restore self. toRight. constant-= (text. bounds. width-10) sender. image = UIImage (named: "fa-right ")}}
8. Simple encapsulation of the prompt text function
// Copy the showtext. swift file to the project Notice. showText ("", fontsize: fontSize, obliqueness: 0) // a prompt is displayed.
9. Set click to hide the navigation bar and set to slide to hide the navigation bar.
Self. navigationController ?. HidesBarsOnTap = false // click to hide the navigation bar. If the value is false, self. navigationController is canceled ?. HidesBarsOnSwipe = true // you can slide to hide the navigation bar.
10. solve the problem that the cursor is not at the bottom of UITextView.
/* When UITextView is used, the cursor is usually not at the bottom... (IOS8) solution: 1. First, remove all Padding: self. text. textContainerInset = UIEdgeInsetsZero self. text. textContainer. lineFragmentPadding = 0 2. Add a row in the delegate method: func textViewDidChange (textView: UITextView) {self. text. scrollRangeToVisible (self. text. selectedRange)} ps: The delegate method is at the bottom. */Self. text. textContainerInset = UIEdgeInsetsZero self. text. textContainer. lineFragmentPadding = 0
Project address
Github address
Https://github.com/lfb-cd/TextEditorDemo
If there is an update on Weibo, a message will be sent: My weibo
Effect browsing:
(Gifpicture about 10 MB ):