Commit c693872f by Daniel Dahan

editor: reworked TextStorage and Text into Editor

parent b55650de
...@@ -7,6 +7,19 @@ ...@@ -7,6 +7,19 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
961276631DCD8B1800A7D920 /* CharacterAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = 961276621DCD8B1800A7D920 /* CharacterAttribute.swift */; };
961276641DCD8CF200A7D920 /* PresenterCard.swift in Headers */ = {isa = PBXBuildFile; fileRef = 9631A7C01D95E3AC00CFB109 /* PresenterCard.swift */; settings = {ATTRIBUTES = (Public, ); }; };
961276651DCD8CF200A7D920 /* Capture.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96717B0D1DBE6AF600DA84DB /* Capture.swift */; settings = {ATTRIBUTES = (Public, ); }; };
961276661DCD8CF200A7D920 /* CapturePreview.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96717B0F1DBE6AF600DA84DB /* CapturePreview.swift */; settings = {ATTRIBUTES = (Public, ); }; };
961276671DCD8CF200A7D920 /* CaptureController.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96717B0E1DBE6AF600DA84DB /* CaptureController.swift */; settings = {ATTRIBUTES = (Public, ); }; };
961276681DCD8CF200A7D920 /* Editor.swift in Headers */ = {isa = PBXBuildFile; fileRef = 961DED451DCC40C500F425B6 /* Editor.swift */; settings = {ATTRIBUTES = (Public, ); }; };
961276691DCD8CF200A7D920 /* EditorController.swift in Headers */ = {isa = PBXBuildFile; fileRef = 961DED4A1DCC546100F425B6 /* EditorController.swift */; settings = {ATTRIBUTES = (Public, ); }; };
9612766A1DCD8CF200A7D920 /* HeightPreset.swift in Headers */ = {isa = PBXBuildFile; fileRef = 9626CB9A1DAD3D1D003E2611 /* HeightPreset.swift */; settings = {ATTRIBUTES = (Public, ); }; };
9612766B1DCD8CF200A7D920 /* PhotoLibrary.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96717B161DBE6B1800DA84DB /* PhotoLibrary.swift */; settings = {ATTRIBUTES = (Public, ); }; };
9612766C1DCD8CF200A7D920 /* PhotoLibraryController.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96717B171DBE6B1800DA84DB /* PhotoLibraryController.swift */; settings = {ATTRIBUTES = (Public, ); }; };
9612766D1DCD8CF200A7D920 /* Pulse.swift in Headers */ = {isa = PBXBuildFile; fileRef = 9631A7C61D95E5D900CFB109 /* Pulse.swift */; settings = {ATTRIBUTES = (Public, ); }; };
9612766E1DCD8CF200A7D920 /* Display.swift in Headers */ = {isa = PBXBuildFile; fileRef = 9626CA961DAB53A8003E2611 /* Display.swift */; settings = {ATTRIBUTES = (Public, ); }; };
9612766F1DCD8CF200A7D920 /* CharacterAttribute.swift in Headers */ = {isa = PBXBuildFile; fileRef = 961276621DCD8B1800A7D920 /* CharacterAttribute.swift */; settings = {ATTRIBUTES = (Public, ); }; };
961DED461DCC40C500F425B6 /* Editor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 961DED451DCC40C500F425B6 /* Editor.swift */; }; 961DED461DCC40C500F425B6 /* Editor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 961DED451DCC40C500F425B6 /* Editor.swift */; };
961DED4B1DCC546100F425B6 /* EditorController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 961DED4A1DCC546100F425B6 /* EditorController.swift */; }; 961DED4B1DCC546100F425B6 /* EditorController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 961DED4A1DCC546100F425B6 /* EditorController.swift */; };
961EFC581D738FF600E84652 /* SnackbarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 961EFC571D738FF600E84652 /* SnackbarController.swift */; }; 961EFC581D738FF600E84652 /* SnackbarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 961EFC571D738FF600E84652 /* SnackbarController.swift */; };
...@@ -99,7 +112,6 @@ ...@@ -99,7 +112,6 @@
96BCB7E11CB40DC500C806FE /* Bar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96BCB7981CB40DC500C806FE /* Bar.swift */; }; 96BCB7E11CB40DC500C806FE /* Bar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96BCB7981CB40DC500C806FE /* Bar.swift */; };
96BCB7E21CB40DC500C806FE /* RootController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96BCB7991CB40DC500C806FE /* RootController.swift */; }; 96BCB7E21CB40DC500C806FE /* RootController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96BCB7991CB40DC500C806FE /* RootController.swift */; };
96BCB7E31CB40DC500C806FE /* TabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96BCB79A1CB40DC500C806FE /* TabBar.swift */; }; 96BCB7E31CB40DC500C806FE /* TabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96BCB79A1CB40DC500C806FE /* TabBar.swift */; };
96BCB7E41CB40DC500C806FE /* Text.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96BCB79B1CB40DC500C806FE /* Text.swift */; };
96BCB7E51CB40DC500C806FE /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96BCB79C1CB40DC500C806FE /* TextField.swift */; }; 96BCB7E51CB40DC500C806FE /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96BCB79C1CB40DC500C806FE /* TextField.swift */; };
96BCB7E61CB40DC500C806FE /* TextStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96BCB79D1CB40DC500C806FE /* TextStorage.swift */; }; 96BCB7E61CB40DC500C806FE /* TextStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96BCB79D1CB40DC500C806FE /* TextStorage.swift */; };
96BCB7E71CB40DC500C806FE /* TextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96BCB79E1CB40DC500C806FE /* TextView.swift */; }; 96BCB7E71CB40DC500C806FE /* TextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96BCB79E1CB40DC500C806FE /* TextView.swift */; };
...@@ -159,7 +171,6 @@ ...@@ -159,7 +171,6 @@
96BCB8461CB4115200C806FE /* NavigationBar.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96BCB7901CB40DC500C806FE /* NavigationBar.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 96BCB8461CB4115200C806FE /* NavigationBar.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96BCB7901CB40DC500C806FE /* NavigationBar.swift */; settings = {ATTRIBUTES = (Public, ); }; };
96BCB8471CB4115200C806FE /* NavigationController.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96BCB7911CB40DC500C806FE /* NavigationController.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 96BCB8471CB4115200C806FE /* NavigationController.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96BCB7911CB40DC500C806FE /* NavigationController.swift */; settings = {ATTRIBUTES = (Public, ); }; };
96BCB8481CB4115200C806FE /* NavigationItem.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96BCB7921CB40DC500C806FE /* NavigationItem.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 96BCB8481CB4115200C806FE /* NavigationItem.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96BCB7921CB40DC500C806FE /* NavigationItem.swift */; settings = {ATTRIBUTES = (Public, ); }; };
96BCB8491CB4115200C806FE /* Text.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96BCB79B1CB40DC500C806FE /* Text.swift */; settings = {ATTRIBUTES = (Public, ); }; };
96BCB84A1CB4115200C806FE /* TextField.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96BCB79C1CB40DC500C806FE /* TextField.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 96BCB84A1CB4115200C806FE /* TextField.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96BCB79C1CB40DC500C806FE /* TextField.swift */; settings = {ATTRIBUTES = (Public, ); }; };
96BCB84B1CB4115200C806FE /* TextStorage.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96BCB79D1CB40DC500C806FE /* TextStorage.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 96BCB84B1CB4115200C806FE /* TextStorage.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96BCB79D1CB40DC500C806FE /* TextStorage.swift */; settings = {ATTRIBUTES = (Public, ); }; };
96BCB84C1CB4115200C806FE /* TextView.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96BCB79E1CB40DC500C806FE /* TextView.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 96BCB84C1CB4115200C806FE /* TextView.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96BCB79E1CB40DC500C806FE /* TextView.swift */; settings = {ATTRIBUTES = (Public, ); }; };
...@@ -205,6 +216,7 @@ ...@@ -205,6 +216,7 @@
/* End PBXContainerItemProxy section */ /* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
961276621DCD8B1800A7D920 /* CharacterAttribute.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CharacterAttribute.swift; sourceTree = "<group>"; };
961DED451DCC40C500F425B6 /* Editor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Editor.swift; sourceTree = "<group>"; }; 961DED451DCC40C500F425B6 /* Editor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Editor.swift; sourceTree = "<group>"; };
961DED4A1DCC546100F425B6 /* EditorController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EditorController.swift; sourceTree = "<group>"; }; 961DED4A1DCC546100F425B6 /* EditorController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EditorController.swift; sourceTree = "<group>"; };
961EFC571D738FF600E84652 /* SnackbarController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SnackbarController.swift; sourceTree = "<group>"; }; 961EFC571D738FF600E84652 /* SnackbarController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SnackbarController.swift; sourceTree = "<group>"; };
...@@ -288,7 +300,6 @@ ...@@ -288,7 +300,6 @@
96BCB7981CB40DC500C806FE /* Bar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Bar.swift; sourceTree = "<group>"; }; 96BCB7981CB40DC500C806FE /* Bar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Bar.swift; sourceTree = "<group>"; };
96BCB7991CB40DC500C806FE /* RootController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RootController.swift; sourceTree = "<group>"; }; 96BCB7991CB40DC500C806FE /* RootController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RootController.swift; sourceTree = "<group>"; };
96BCB79A1CB40DC500C806FE /* TabBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabBar.swift; sourceTree = "<group>"; }; 96BCB79A1CB40DC500C806FE /* TabBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabBar.swift; sourceTree = "<group>"; };
96BCB79B1CB40DC500C806FE /* Text.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Text.swift; sourceTree = "<group>"; };
96BCB79C1CB40DC500C806FE /* TextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextField.swift; sourceTree = "<group>"; }; 96BCB79C1CB40DC500C806FE /* TextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextField.swift; sourceTree = "<group>"; };
96BCB79D1CB40DC500C806FE /* TextStorage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextStorage.swift; sourceTree = "<group>"; }; 96BCB79D1CB40DC500C806FE /* TextStorage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextStorage.swift; sourceTree = "<group>"; };
96BCB79E1CB40DC500C806FE /* TextView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextView.swift; sourceTree = "<group>"; }; 96BCB79E1CB40DC500C806FE /* TextView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextView.swift; sourceTree = "<group>"; };
...@@ -772,7 +783,7 @@ ...@@ -772,7 +783,7 @@
96BCB80E1CB4110E00C806FE /* TextView */ = { 96BCB80E1CB4110E00C806FE /* TextView */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
96BCB79B1CB40DC500C806FE /* Text.swift */, 961276621DCD8B1800A7D920 /* CharacterAttribute.swift */,
96BCB79D1CB40DC500C806FE /* TextStorage.swift */, 96BCB79D1CB40DC500C806FE /* TextStorage.swift */,
96BCB79E1CB40DC500C806FE /* TextView.swift */, 96BCB79E1CB40DC500C806FE /* TextView.swift */,
); );
...@@ -845,7 +856,6 @@ ...@@ -845,7 +856,6 @@
96BCB8461CB4115200C806FE /* NavigationBar.swift in Headers */, 96BCB8461CB4115200C806FE /* NavigationBar.swift in Headers */,
96BCB8471CB4115200C806FE /* NavigationController.swift in Headers */, 96BCB8471CB4115200C806FE /* NavigationController.swift in Headers */,
96BCB8481CB4115200C806FE /* NavigationItem.swift in Headers */, 96BCB8481CB4115200C806FE /* NavigationItem.swift in Headers */,
96BCB8491CB4115200C806FE /* Text.swift in Headers */,
96BCB84A1CB4115200C806FE /* TextField.swift in Headers */, 96BCB84A1CB4115200C806FE /* TextField.swift in Headers */,
96BCB84B1CB4115200C806FE /* TextStorage.swift in Headers */, 96BCB84B1CB4115200C806FE /* TextStorage.swift in Headers */,
96BCB84C1CB4115200C806FE /* TextView.swift in Headers */, 96BCB84C1CB4115200C806FE /* TextView.swift in Headers */,
...@@ -875,6 +885,18 @@ ...@@ -875,6 +885,18 @@
9697F7C61D8F2573004741EC /* PageTabBarController.swift in Headers */, 9697F7C61D8F2573004741EC /* PageTabBarController.swift in Headers */,
9697F7CB1D8F2573004741EC /* Snackbar.swift in Headers */, 9697F7CB1D8F2573004741EC /* Snackbar.swift in Headers */,
9697F7CC1D8F2573004741EC /* SnackbarController.swift in Headers */, 9697F7CC1D8F2573004741EC /* SnackbarController.swift in Headers */,
961276641DCD8CF200A7D920 /* PresenterCard.swift in Headers */,
961276651DCD8CF200A7D920 /* Capture.swift in Headers */,
961276661DCD8CF200A7D920 /* CapturePreview.swift in Headers */,
961276671DCD8CF200A7D920 /* CaptureController.swift in Headers */,
961276681DCD8CF200A7D920 /* Editor.swift in Headers */,
961276691DCD8CF200A7D920 /* EditorController.swift in Headers */,
9612766A1DCD8CF200A7D920 /* HeightPreset.swift in Headers */,
9612766B1DCD8CF200A7D920 /* PhotoLibrary.swift in Headers */,
9612766C1DCD8CF200A7D920 /* PhotoLibraryController.swift in Headers */,
9612766D1DCD8CF200A7D920 /* Pulse.swift in Headers */,
9612766E1DCD8CF200A7D920 /* Display.swift in Headers */,
9612766F1DCD8CF200A7D920 /* CharacterAttribute.swift in Headers */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
...@@ -1143,9 +1165,9 @@ ...@@ -1143,9 +1165,9 @@
96BCB7CD1CB40DC500C806FE /* PulseView.swift in Sources */, 96BCB7CD1CB40DC500C806FE /* PulseView.swift in Sources */,
96BCB7DA1CB40DC500C806FE /* NavigationController.swift in Sources */, 96BCB7DA1CB40DC500C806FE /* NavigationController.swift in Sources */,
96BCB7A81CB40DC500C806FE /* FabButton.swift in Sources */, 96BCB7A81CB40DC500C806FE /* FabButton.swift in Sources */,
96BCB7E41CB40DC500C806FE /* Text.swift in Sources */,
96717B121DBE6AF600DA84DB /* CaptureController.swift in Sources */, 96717B121DBE6AF600DA84DB /* CaptureController.swift in Sources */,
96717B181DBE6B1800DA84DB /* PhotoLibrary.swift in Sources */, 96717B181DBE6B1800DA84DB /* PhotoLibrary.swift in Sources */,
961276631DCD8B1800A7D920 /* CharacterAttribute.swift in Sources */,
96BCB7AB1CB40DC500C806FE /* ImageCard.swift in Sources */, 96BCB7AB1CB40DC500C806FE /* ImageCard.swift in Sources */,
96BCB7CB1CB40DC500C806FE /* PulseAnimation.swift in Sources */, 96BCB7CB1CB40DC500C806FE /* PulseAnimation.swift in Sources */,
96BCB7AE1CB40DC500C806FE /* Material+UIFont.swift in Sources */, 96BCB7AE1CB40DC500C806FE /* Material+UIFont.swift in Sources */,
......
/*
* Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. <http://cosmicmind.com>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of CosmicMind nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import UIKit
public enum CharacterAttribute: String {
case font = "NSFontAttributeName"
case paragraphStyle = "NSParagraphStyleAttributeName"
case forgroundColor = "NSForegroundColorAttributeName"
case backgroundColor = "NSBackgroundColorAttributeName"
case ligature = "NSLigatureAttributeName"
case kern = "NSKernAttributeName"
case strikethroughStyle = "NSStrikethroughStyleAttributeName"
case underlineStyle = "NSUnderlineStyleAttributeName"
case strokeColor = "NSStrokeColorAttributeName"
case strokeWidth = "NSStrokeWidthAttributeName"
case shadow = "NSShadowAttributeName"
case textEffect = "NSTextEffectAttributeName"
case attachment = "NSAttachmentAttributeName"
case link = "NSLinkAttributeName"
case baselineOffset = "NSBaselineOffsetAttributeName"
case underlineColor = "NSUnderlineColorAttributeName"
case strikethroughColor = "NSStrikethroughColorAttributeName"
case obliqueness = "NSObliquenessAttributeName"
case expansion = "NSExpansionAttributeName"
case writingDirection = "NSWritingDirectionAttributeName"
case verticalGlyphForm = "NSVerticalGlyphFormAttributeName"
}
public func CharacterAttributeToValue(attribute: CharacterAttribute) -> String {
switch attribute {
case .font:
return NSFontAttributeName
case .paragraphStyle:
return NSParagraphStyleAttributeName
case .forgroundColor:
return NSForegroundColorAttributeName
case .backgroundColor:
return NSBackgroundColorAttributeName
case .ligature:
return NSLigatureAttributeName
case .kern:
return NSKernAttributeName
case .strikethroughStyle:
return NSStrikethroughStyleAttributeName
case .underlineStyle:
return NSUnderlineStyleAttributeName
case .strokeColor:
return NSStrokeColorAttributeName
case .strokeWidth:
return NSStrokeWidthAttributeName
case .shadow:
return NSShadowAttributeName
case .textEffect:
return NSTextEffectAttributeName
case .attachment:
return NSAttachmentAttributeName
case .link:
return NSLinkAttributeName
case .baselineOffset:
return NSBaselineOffsetAttributeName
case .underlineColor:
return NSUnderlineColorAttributeName
case .strikethroughColor:
return NSStrikethroughColorAttributeName
case .obliqueness:
return NSObliquenessAttributeName
case .expansion:
return NSExpansionAttributeName
case .writingDirection:
return NSWritingDirectionAttributeName
case .verticalGlyphForm:
return NSVerticalGlyphFormAttributeName
}
}
extension NSAttributedString {
/**
Retrieves the character attributes that are currently applied.
- Parameter at location: An Int.
- Parameter effectiveRange: An optional NSRangePointer.
- Returns: A Dictionary of CharacterAttribute type keys and Any type values.
*/
open func characterAttributes(at location: Int, effectiveRange: NSRangePointer?) -> [CharacterAttribute: Any] {
var ca = [CharacterAttribute: Any]()
attributes(at: location, effectiveRange: effectiveRange).forEach { (key, value) in
guard let attribute = CharacterAttribute.init(rawValue: key) else {
return
}
ca[attribute] = value
}
return ca
}
}
extension NSMutableAttributedString {
/**
Adds a character attribute to a given range.
- Parameter characterAttribute: A CharacterAttribute.
- Parameter value: Any type.
- Parameter range: A NSRange.
*/
open func addAttribute(characterAttribute: CharacterAttribute, value: Any, range: NSRange) {
addAttribute(characterAttribute.rawValue, value: value, range: range)
}
/**
Removes a character attribute from a given range.
- Parameter characterAttribute: A CharacterAttribute.
- Parameter range: A NSRange.
*/
open func removeAttribute(characterAttribute: CharacterAttribute, range: NSRange) {
removeAttribute(characterAttribute.rawValue, range: range)
}
}
...@@ -30,130 +30,44 @@ ...@@ -30,130 +30,44 @@
import UIKit import UIKit
public enum CharacterAttribute: String {
case font = "NSFontAttributeName"
case paragraphStyle = "NSParagraphStyleAttributeName"
case forgroundColor = "NSForegroundColorAttributeName"
case backgroundColor = "NSBackgroundColorAttributeName"
case ligature = "NSLigatureAttributeName"
case kern = "NSKernAttributeName"
case strikethroughStyle = "NSStrikethroughStyleAttributeName"
case underlineStyle = "NSUnderlineStyleAttributeName"
case strokeColor = "NSStrokeColorAttributeName"
case strokeWidth = "NSStrokeWidthAttributeName"
case shadow = "NSShadowAttributeName"
case textEffect = "NSTextEffectAttributeName"
case attachment = "NSAttachmentAttributeName"
case link = "NSLinkAttributeName"
case baselineOffset = "NSBaselineOffsetAttributeName"
case underlineColor = "NSUnderlineColorAttributeName"
case strikethroughColor = "NSStrikethroughColorAttributeName"
case obliqueness = "NSObliquenessAttributeName"
case expansion = "NSExpansionAttributeName"
case writingDirection = "NSWritingDirectionAttributeName"
case verticalGlyphForm = "NSVerticalGlyphFormAttributeName"
}
public func CharacterAttributeToValue(attribute: CharacterAttribute) -> String {
switch attribute {
case .font:
return NSFontAttributeName
case .paragraphStyle:
return NSParagraphStyleAttributeName
case .forgroundColor:
return NSForegroundColorAttributeName
case .backgroundColor:
return NSBackgroundColorAttributeName
case .ligature:
return NSLigatureAttributeName
case .kern:
return NSKernAttributeName
case .strikethroughStyle:
return NSStrikethroughStyleAttributeName
case .underlineStyle:
return NSUnderlineStyleAttributeName
case .strokeColor:
return NSStrokeColorAttributeName
case .strokeWidth:
return NSStrokeWidthAttributeName
case .shadow:
return NSShadowAttributeName
case .textEffect:
return NSTextEffectAttributeName
case .attachment:
return NSAttachmentAttributeName
case .link:
return NSLinkAttributeName
case .baselineOffset:
return NSBaselineOffsetAttributeName
case .underlineColor:
return NSUnderlineColorAttributeName
case .strikethroughColor:
return NSStrikethroughColorAttributeName
case .obliqueness:
return NSObliquenessAttributeName
case .expansion:
return NSExpansionAttributeName
case .writingDirection:
return NSWritingDirectionAttributeName
case .verticalGlyphForm:
return NSVerticalGlyphFormAttributeName
}
}
/// A memory reference to the CharacterAttribute instance for String extensions.
//private var CharacterAttributeKey: UInt8 = 0
//public struct CharacterAttribute {
//}
//extension String {
/// characterAttribute reference.
// public private(set) var characterAttribute: CharacterAttribute {
// get {
// return AssociatedObject(base: self, key: &CharacterAttributeKey) {
// return CharacterAttribute()
// }
// }
// set(value) {
// AssociateObject(base: self, key: &CharacterAttributeKey, value: value)
// }
// }
//}
extension NSAttributedString {
open func characterAttributes(at index: Int, effectiveRange: NSRangePointer?) -> [CharacterAttribute: Any] {
var ca = [CharacterAttribute: Any]()
attributes(at: index, effectiveRange: effectiveRange).forEach { (key, value) in
guard let attribute = CharacterAttribute.init(rawValue: key) else {
return
}
ca[attribute] = value
}
return ca
}
}
public enum ParagraphAttribute {
}
public enum DocumentAttribute {
}
@objc(EditorDelegate) @objc(EditorDelegate)
public protocol EditorDelegate { public protocol EditorDelegate {
/**
An optional delegation method that is executed when
text will be processed during editing.
- Parameter text: The Text instance assodicated with the
delegation object.
- Parameter textStorage: The TextStorage instance
associated with the delegation object.
- Parameter string: The string value that is currently
being edited.
- Parameter range: The range of characters that are being
edited.
*/
@objc
optional func editor(editor: Editor, willProcess textStorage: TextStorage, string: String, range: NSRange)
/**
An optional delegation method that is executed after
the edit processing has completed.
- Parameter text: The Text instance assodicated with the
delegation object.
- Parameter textStorage: The TextStorage instance
associated with the delegation object.
- Parameter string: The string value that was edited.
- Parameter result: A NSTextCheckingResult associated
with the processing result.
- Parameter flags: Matching flags.
- Parameter stop: Halts a service which is either
publishing or resolving.
*/
@objc
optional func editor(editor: Editor, didProcess textStorage: TextStorage, string: String, result: NSTextCheckingResult?, flags: NSRegularExpression.MatchingFlags, stop: UnsafeMutablePointer<ObjCBool>)
} }
open class Editor: View { open class Editor: View {
/// A reference to the Text. /// TextStorage instance that is observed while editing.
open fileprivate(set) var text: Text! open fileprivate(set) var textStorage: TextStorage!
/// A reference to the NSTextContainer. /// A reference to the NSTextContainer.
open fileprivate(set) var textContainer: NSTextContainer! open fileprivate(set) var textContainer: NSTextContainer!
...@@ -167,6 +81,37 @@ open class Editor: View { ...@@ -167,6 +81,37 @@ open class Editor: View {
/// A reference to an EditorDelegate. /// A reference to an EditorDelegate.
open weak var delegate: EditorDelegate? open weak var delegate: EditorDelegate?
/// The string pattern to match within the textStorage.
open var pattern = "(^|\\s)#[\\d\\w_\u{203C}\u{2049}\u{20E3}\u{2122}\u{2139}\u{2194}-\u{2199}\u{21A9}-\u{21AA}\u{231A}-\u{231B}\u{23E9}-\u{23EC}\u{23F0}\u{23F3}\u{24C2}\u{25AA}-\u{25AB}\u{25B6}\u{25C0}\u{25FB}-\u{25FE}\u{2600}-\u{2601}\u{260E}\u{2611}\u{2614}-\u{2615}\u{261D}\u{263A}\u{2648}-\u{2653}\u{2660}\u{2663}\u{2665}-\u{2666}\u{2668}\u{267B}\u{267F}\u{2693}\u{26A0}-\u{26A1}\u{26AA}-\u{26AB}\u{26BD}-\u{26BE}\u{26C4}-\u{26C5}\u{26CE}\u{26D4}\u{26EA}\u{26F2}-\u{26F3}\u{26F5}\u{26FA}\u{26FD}\u{2702}\u{2705}\u{2708}-\u{270C}\u{270F}\u{2712}\u{2714}\u{2716}\u{2728}\u{2733}-\u{2734}\u{2744}\u{2747}\u{274C}\u{274E}\u{2753}-\u{2755}\u{2757}\u{2764}\u{2795}-\u{2797}\u{27A1}\u{27B0}\u{2934}-\u{2935}\u{2B05}-\u{2B07}\u{2B1B}-\u{2B1C}\u{2B50}\u{2B55}\u{3030}\u{303D}\u{3297}\u{3299}\u{1F004}\u{1F0CF}\u{1F170}-\u{1F171}\u{1F17E}-\u{1F17F}\u{1F18E}\u{1F191}-\u{1F19A}\u{1F1E7}-\u{1F1EC}\u{1F1EE}-\u{1F1F0}\u{1F1F3}\u{1F1F5}\u{1F1F7}-\u{1F1FA}\u{1F201}-\u{1F202}\u{1F21A}\u{1F22F}\u{1F232}-\u{1F23A}\u{1F250}-\u{1F251}\u{1F300}-\u{1F320}\u{1F330}-\u{1F335}\u{1F337}-\u{1F37C}\u{1F380}-\u{1F393}\u{1F3A0}-\u{1F3C4}\u{1F3C6}-\u{1F3CA}\u{1F3E0}-\u{1F3F0}\u{1F400}-\u{1F43E}\u{1F440}\u{1F442}-\u{1F4F7}\u{1F4F9}-\u{1F4FC}\u{1F500}-\u{1F507}\u{1F509}-\u{1F53D}\u{1F550}-\u{1F567}\u{1F5FB}-\u{1F640}\u{1F645}-\u{1F64F}\u{1F680}-\u{1F68A}]+" {
didSet {
prepareRegularExpression()
}
}
/**
A convenience property that accesses the textStorage
string.
*/
open var string: String {
return textStorage.string
}
/// An Array of matches that match the pattern expression.
open var matches: [String] {
return textStorage.expression!.matches(in: string, options: [], range: NSMakeRange(0, string.utf16.count)).map { [unowned self] in
(self.string as NSString).substring(with: $0.range).trimmed
}
}
/**
An Array of unique matches that match the pattern
expression.
*/
public var uniqueMatches: [String] {
var seen = [String: Bool]()
return matches.filter { nil == seen.updateValue(true, forKey: $0) }
}
/** /**
Prepares the view instance when intialized. When subclassing, Prepares the view instance when intialized. When subclassing,
it is recommended to override the prepare method it is recommended to override the prepare method
...@@ -178,7 +123,7 @@ open class Editor: View { ...@@ -178,7 +123,7 @@ open class Editor: View {
super.prepare() super.prepare()
prepareTextContainer() prepareTextContainer()
prepareLayoutManager() prepareLayoutManager()
prepareText() prepareTextStorage()
prepareTextView() prepareTextView()
} }
} }
...@@ -195,11 +140,11 @@ extension Editor { ...@@ -195,11 +140,11 @@ extension Editor {
layoutManager.addTextContainer(textContainer) layoutManager.addTextContainer(textContainer)
} }
/// PRepares the text. /// Prepares the textStorage.
fileprivate func prepareText() { fileprivate func prepareTextStorage() {
text = Text() textStorage = TextStorage()
text.delegate = self textStorage.addLayoutManager(layoutManager)
text.textStorage.addLayoutManager(layoutManager) textStorage.delegate = self
} }
/// Prepares the textView. /// Prepares the textView.
...@@ -207,23 +152,19 @@ extension Editor { ...@@ -207,23 +152,19 @@ extension Editor {
textView = TextView(textContainer: textContainer) textView = TextView(textContainer: textContainer)
layout(textView).edges() layout(textView).edges()
} }
/// Prepares the regular expression for matching.
fileprivate func prepareRegularExpression() {
textStorage.expression = try? NSRegularExpression(pattern: pattern, options: [])
}
} }
extension Editor: TextDelegate { extension Editor: TextStorageDelegate {
/** open func textStorage(textStorage: TextStorage, willProcessEditing text: String, range: NSRange) {
When changes in the textView text are made, this delegation method
is executed with the added text string and range.
*/
public func textWillProcessEdit(text: Text, textStorage: TextStorage, string: String, range: NSRange) {
textStorage.removeAttribute(CharacterAttribute.font.rawValue, range: range)
textStorage.addAttribute(CharacterAttribute.font.rawValue, value: RobotoFont.regular, range: range)
} }
/** open func textStorage(textStorage: TextStorage, didProcessEditing text: String, result: NSTextCheckingResult?, flags: NSRegularExpression.MatchingFlags, stop: UnsafeMutablePointer<ObjCBool>) {
When a match is detected within the textView text, this delegation
method is executed with the added text string and range.
*/
public func textDidProcessEdit(text: Text, textStorage: TextStorage, string: String, result: NSTextCheckingResult?, flags: NSRegularExpression.MatchingFlags, stop: UnsafeMutablePointer<ObjCBool>) {
textStorage.addAttribute(CharacterAttribute.font.rawValue, value: RobotoFont.bold, range: result!.range)
} }
} }
/*
* Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. <http://cosmicmind.com>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of CosmicMind nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import UIKit
@objc(TextDelegate)
public protocol TextDelegate {
/**
An optional delegation method that is executed when
text will be processed during editing.
- Parameter text: The Text instance assodicated with the
delegation object.
- Parameter textStorage: The TextStorage instance
associated with the delegation object.
- Parameter string: The string value that is currently
being edited.
- Parameter range: The range of characters that are being
edited.
*/
@objc
optional func textWillProcessEdit(text: Text, textStorage: TextStorage, string: String, range: NSRange)
/**
An optional delegation method that is executed after
the edit processing has completed.
- Parameter text: The Text instance assodicated with the
delegation object.
- Parameter textStorage: The TextStorage instance
associated with the delegation object.
- Parameter string: The string value that was edited.
- Parameter result: A NSTextCheckingResult associated
with the processing result.
- Parameter flags: Matching flags.
- Parameter stop: Halts a service which is either
publishing or resolving.
*/
@objc
optional func textDidProcessEdit(text: Text, textStorage: TextStorage, string: String, result: NSTextCheckingResult?, flags: NSRegularExpression.MatchingFlags, stop: UnsafeMutablePointer<ObjCBool>)
}
@objc(Text)
public class Text: NSObject {
/// The string pattern to match within the textStorage.
public var pattern: String = "(^|\\s)#[\\d\\w_\u{203C}\u{2049}\u{20E3}\u{2122}\u{2139}\u{2194}-\u{2199}\u{21A9}-\u{21AA}\u{231A}-\u{231B}\u{23E9}-\u{23EC}\u{23F0}\u{23F3}\u{24C2}\u{25AA}-\u{25AB}\u{25B6}\u{25C0}\u{25FB}-\u{25FE}\u{2600}-\u{2601}\u{260E}\u{2611}\u{2614}-\u{2615}\u{261D}\u{263A}\u{2648}-\u{2653}\u{2660}\u{2663}\u{2665}-\u{2666}\u{2668}\u{267B}\u{267F}\u{2693}\u{26A0}-\u{26A1}\u{26AA}-\u{26AB}\u{26BD}-\u{26BE}\u{26C4}-\u{26C5}\u{26CE}\u{26D4}\u{26EA}\u{26F2}-\u{26F3}\u{26F5}\u{26FA}\u{26FD}\u{2702}\u{2705}\u{2708}-\u{270C}\u{270F}\u{2712}\u{2714}\u{2716}\u{2728}\u{2733}-\u{2734}\u{2744}\u{2747}\u{274C}\u{274E}\u{2753}-\u{2755}\u{2757}\u{2764}\u{2795}-\u{2797}\u{27A1}\u{27B0}\u{2934}-\u{2935}\u{2B05}-\u{2B07}\u{2B1B}-\u{2B1C}\u{2B50}\u{2B55}\u{3030}\u{303D}\u{3297}\u{3299}\u{1F004}\u{1F0CF}\u{1F170}-\u{1F171}\u{1F17E}-\u{1F17F}\u{1F18E}\u{1F191}-\u{1F19A}\u{1F1E7}-\u{1F1EC}\u{1F1EE}-\u{1F1F0}\u{1F1F3}\u{1F1F5}\u{1F1F7}-\u{1F1FA}\u{1F201}-\u{1F202}\u{1F21A}\u{1F22F}\u{1F232}-\u{1F23A}\u{1F250}-\u{1F251}\u{1F300}-\u{1F320}\u{1F330}-\u{1F335}\u{1F337}-\u{1F37C}\u{1F380}-\u{1F393}\u{1F3A0}-\u{1F3C4}\u{1F3C6}-\u{1F3CA}\u{1F3E0}-\u{1F3F0}\u{1F400}-\u{1F43E}\u{1F440}\u{1F442}-\u{1F4F7}\u{1F4F9}-\u{1F4FC}\u{1F500}-\u{1F507}\u{1F509}-\u{1F53D}\u{1F550}-\u{1F567}\u{1F5FB}-\u{1F640}\u{1F645}-\u{1F64F}\u{1F680}-\u{1F68A}]+" {
didSet {
prepareTextStorageExpression()
}
}
/// TextStorage instance that is observed while editing.
public private(set) var textStorage: TextStorage = TextStorage()
/// Delegation object for pre and post text processing.
open weak var delegate: TextDelegate?
/// Initializer.
public override init() {
super.init()
prepareTextStorageExpression()
prepareTextStorageProcessingCallbacks()
}
/**
A convenience property that accesses the textStorage
string.
*/
public var string: String {
return textStorage.string
}
/// An Array of matches that match the pattern expression.
public var matches: Array<String> {
return textStorage.expression!.matches(in: string, options: [], range: NSMakeRange(0, string.utf16.count)).map { [unowned self] in
(self.string as NSString).substring(with: $0.range).trimmed
}
}
/**
An Array of unique matches that match the pattern
expression.
*/
public var uniqueMatches: Array<String> {
var seen: [String: Bool] = [:]
return matches.filter { nil == seen.updateValue(true, forKey: $0) }
}
/// Prepares the TextStorage regular expression for matching.
private func prepareTextStorageExpression() {
textStorage.expression = try? NSRegularExpression(pattern: pattern, options: [])
}
/// Prepares the pre and post processing callbacks.
private func prepareTextStorageProcessingCallbacks() {
textStorage.textWillProcessEdit = { [weak self] (textStorage: TextStorage, string: String, range: NSRange) -> Void in
if let s: Text = self {
s.delegate?.textWillProcessEdit?(text: s, textStorage: textStorage, string: string, range: range)
}
}
textStorage.textDidProcessEdit = { [weak self] (textStorage: TextStorage, result: NSTextCheckingResult?, flags: NSRegularExpression.MatchingFlags, stop: UnsafeMutablePointer<ObjCBool>) -> Void in
if let s: Text = self {
s.delegate?.textDidProcessEdit?(text: s, textStorage: textStorage, string: textStorage.string, result: result, flags: flags, stop: stop)
}
}
}
}
...@@ -30,21 +30,37 @@ ...@@ -30,21 +30,37 @@
import UIKit import UIKit
internal typealias TextWillProcessEdit = (TextStorage, String, NSRange) -> Void @objc(TextStorageDelegate)
internal typealias TextDidProcessEdit = (TextStorage, NSTextCheckingResult?, NSRegularExpression.MatchingFlags, UnsafeMutablePointer<ObjCBool>) -> Void public protocol TextStorageDelegate: NSTextStorageDelegate {
/**
public class TextStorage: NSTextStorage { A delegation method that is executed when text will be
/// A callback that is executed when a process edit will happen. processed during editing.
internal var textWillProcessEdit: TextWillProcessEdit? - Parameter textStorage: A TextStorage.
- Parameter willProcessEditing text: A String.
- Parameter range: A NSRange.
*/
@objc
optional func textStorage(textStorage: TextStorage, willProcessEditing text: String, range: NSRange)
/// A callback that is executed when a process edit did happen. /**
internal var textDidProcessEdit: TextDidProcessEdit? A delegation method that is executed when text has been
processed after editing.
- Parameter textStorage: A TextStorage.
- Parameter didProcessEditing text: A String.
- Parameter result: An optional NSTextCheckingResult.
- Parameter flags: NSRegularExpression.MatchingFlags.
- Parameter top: An UnsafeMutablePointer<ObjCBool>.
*/
@objc
optional func textStorage(textStorage: TextStorage, didProcessEditing text: String, result: NSTextCheckingResult?, flags: NSRegularExpression.MatchingFlags, stop: UnsafeMutablePointer<ObjCBool>)
}
open class TextStorage: NSTextStorage {
/// A storage facility for attributed text. /// A storage facility for attributed text.
public lazy var store: NSMutableAttributedString = NSMutableAttributedString() open fileprivate(set) var store: NSMutableAttributedString!
/// The regular expression to match text fragments against. /// The regular expression to match text fragments against.
public var expression: NSRegularExpression? open var expression: NSRegularExpression?
/// Initializer. /// Initializer.
public required init?(coder aDecoder: NSCoder) { public required init?(coder aDecoder: NSCoder) {
...@@ -54,22 +70,38 @@ public class TextStorage: NSTextStorage { ...@@ -54,22 +70,38 @@ public class TextStorage: NSTextStorage {
/// Initializer. /// Initializer.
public override init() { public override init() {
super.init() super.init()
prepareStore()
}
}
extension TextStorage {
/// Prepare the store.
fileprivate func prepareStore() {
store = NSMutableAttributedString()
} }
}
extension TextStorage {
/// A String value of the attirbutedString property. /// A String value of the attirbutedString property.
public override var string: String { open override var string: String {
return store.string return store.string
} }
/// Processes the text when editing. /// Processes the text when editing.
public override func processEditing() { open override func processEditing() {
let range: NSRange = (string as NSString).paragraphRange(for: editedRange) let range: NSRange = (string as NSString).paragraphRange(for: editedRange)
textWillProcessEdit?(self, string, range) (delegate as? TextStorageDelegate)?.textStorage?(textStorage: self, willProcessEditing: string, range: range)
expression!.enumerateMatches(in: string, options: [], range: range) { [weak self] (result: NSTextCheckingResult?, flags: NSRegularExpression.MatchingFlags, stop: UnsafeMutablePointer<ObjCBool>) -> Void in
guard let s = self else {
return
}
expression!.enumerateMatches(in: string, options: [], range: range) { (result: NSTextCheckingResult?, flags: NSRegularExpression.MatchingFlags, stop: UnsafeMutablePointer<ObjCBool>) -> Void in (s.delegate as? TextStorageDelegate)?.textStorage!(textStorage: s, didProcessEditing: s.string, result: result, flags: flags, stop: stop)
self.textDidProcessEdit?(self, result, flags, stop)
} }
super.processEditing() super.processEditing()
} }
...@@ -85,7 +117,7 @@ public class TextStorage: NSTextStorage { ...@@ -85,7 +117,7 @@ public class TextStorage: NSTextStorage {
If you don't need this value, pass NULL. If you don't need this value, pass NULL.
- Returns: The attributes for the character at index. - Returns: The attributes for the character at index.
*/ */
public override func attributes(at location: Int, effectiveRange range: NSRangePointer?) -> [String : Any] { open override func attributes(at location: Int, effectiveRange range: NSRangePointer?) -> [String : Any] {
return store.attributes(at: location, effectiveRange: range) return store.attributes(at: location, effectiveRange: range)
} }
...@@ -95,9 +127,10 @@ public class TextStorage: NSTextStorage { ...@@ -95,9 +127,10 @@ public class TextStorage: NSTextStorage {
- Parameter str: The string value that the characters - Parameter str: The string value that the characters
will be replaced with. will be replaced with.
*/ */
public override func replaceCharacters(in range: NSRange, with str: String) { open override func replaceCharacters(in range: NSRange, with str: String) {
store.replaceCharacters(in: range, with: str) store.replaceCharacters(in: range, with: str)
edited(NSTextStorageEditActions.editedCharacters, range: range, changeInLength: str.utf16.count - range.length)
edited(.editedCharacters, range: range, changeInLength: str.utf16.count - range.length)
} }
/** /**
...@@ -106,8 +139,9 @@ public class TextStorage: NSTextStorage { ...@@ -106,8 +139,9 @@ public class TextStorage: NSTextStorage {
- Parameter range: A range of characters that will have their - Parameter range: A range of characters that will have their
attributes updated. attributes updated.
*/ */
public override func setAttributes(_ attrs: [String : Any]?, range: NSRange) { open override func setAttributes(_ attrs: [String : Any]?, range: NSRange) {
store.setAttributes(attrs, range: range) store.setAttributes(attrs, range: range)
edited(NSTextStorageEditActions.editedAttributes, range: range, changeInLength: 0)
edited(.editedAttributes, range: range, changeInLength: 0)
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment