Skip to content

Commit

Permalink
Improvements to text wrapping, documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
mattmassicotte committed May 7, 2020
1 parent 51d0924 commit bdb89fc
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 23 deletions.
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,21 @@ func replaceCharacters(in range: NSRange, with attributedString: NSAttributedStr
func replaceString(in range: NSRange, with attributedString: NSAttributedString)
```

**Behavior**

Changing NSTextView behaviors can be tricky, and often involve complex interactions with the whole system (NSLayoutManager, NSTextContainer, NSScrollView, etc).

```swift
public var wrapsTextToHorizontalBounds: Bool
```

**Workarounds**

```swift
// Fixes a widely-seen selection drawing artifact
func applySelectionDrawingWorkaround()
```

### Suggestions or Feedback

We'd love to hear from you! Get in touch via [twitter](https://twitter.com/chimehq), an issue, or a pull request.
Expand Down
6 changes: 5 additions & 1 deletion TextViewPlus.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
objects = {

/* Begin PBXBuildFile section */
C908A15A24635F0600ADE4D9 /* NSTextView+Behavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = C908A15924635F0600ADE4D9 /* NSTextView+Behavior.swift */; };
C96AF30F244E1872004EB905 /* NSTextView+Workarounds.swift in Sources */ = {isa = PBXBuildFile; fileRef = C96AF30E244E1872004EB905 /* NSTextView+Workarounds.swift */; };
C9C7D7CD23BF6CCD00282686 /* TextViewPlus.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C9C7D7C323BF6CCC00282686 /* TextViewPlus.framework */; };
C9C7D7D223BF6CCD00282686 /* TextViewPlusTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9C7D7D123BF6CCD00282686 /* TextViewPlusTests.swift */; };
Expand All @@ -31,6 +32,7 @@
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
C908A15924635F0600ADE4D9 /* NSTextView+Behavior.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSTextView+Behavior.swift"; sourceTree = "<group>"; };
C96AF30E244E1872004EB905 /* NSTextView+Workarounds.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSTextView+Workarounds.swift"; sourceTree = "<group>"; };
C9C7D7C323BF6CCC00282686 /* TextViewPlus.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TextViewPlus.framework; sourceTree = BUILT_PRODUCTS_DIR; };
C9C7D7C623BF6CCC00282686 /* TextViewPlus.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TextViewPlus.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -98,6 +100,7 @@
C9C7D7E823BF6F6900282686 /* NSTextView+AttributedString.swift */,
C9C7D7E723BF6E8400282686 /* TextViewPlus.xcconfig */,
C96AF30E244E1872004EB905 /* NSTextView+Workarounds.swift */,
C908A15924635F0600ADE4D9 /* NSTextView+Behavior.swift */,
);
path = TextViewPlus;
sourceTree = "<group>";
Expand Down Expand Up @@ -171,7 +174,7 @@
attributes = {
LastSwiftUpdateCheck = 1130;
LastUpgradeCheck = 1130;
ORGANIZATIONNAME = ChimeHq;
ORGANIZATIONNAME = "Chime Systems Inc";
TargetAttributes = {
C9C7D7C223BF6CCC00282686 = {
CreatedOnToolsVersion = 11.3;
Expand Down Expand Up @@ -244,6 +247,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C908A15A24635F0600ADE4D9 /* NSTextView+Behavior.swift in Sources */,
C96AF30F244E1872004EB905 /* NSTextView+Workarounds.swift in Sources */,
C9C7D7E223BF6D3800282686 /* NSTextView+Ranges.swift in Sources */,
C9C7D7E323BF6D3800282686 /* NSTextView+Selection.swift in Sources */,
Expand Down
61 changes: 61 additions & 0 deletions TextViewPlus/NSTextView+Behavior.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//
// NSTextView+Behavior.swift
// TextViewPlus
//
// Created by Matt Massicotte on 2020-05-06.
// Copyright © 2020 Chime Systems Inc. All rights reserved.
//

import Cocoa

extension NSTextView {
private var maximumUsableWidth: CGFloat {
guard let scrollView = enclosingScrollView else {
return bounds.width
}

let usableWidth = scrollView.contentSize.width - textContainerInset.width

guard scrollView.rulersVisible, let rulerView = scrollView.verticalRulerView else {
return usableWidth
}

return usableWidth - rulerView.requiredThickness
}

// swiftlint:disable line_length
/// Controls the relative sizing behavior of the NSTextView and its NSTextContainer
///
/// NSTextView scrolling behavior is tricky. Correct configuration of the enclosing
/// NSScrollView is required as well. But, this method does the basic setup,
/// as well as adjusting frame positions to account for any NSScrollView rulers.
///
/// Check out: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/TextUILayer/Tasks/TextInScrollView.html
public var wrapsTextToHorizontalBounds: Bool {
get {
guard let container = textContainer else {
return false
}

return container.widthTracksTextView
}
set {
textContainer?.widthTracksTextView = newValue

let max = CGFloat.greatestFiniteMagnitude

textContainer?.size = NSSize(width: max, height: max)

// if we are turning on wrapping, our view could be the wrong size,
// so need to adjust it. Also, the textContainer's width could have
// been set to large, but adjusting the frame will fix that
// automatically
if newValue {
let newSize = NSSize(width: maximumUsableWidth, height: frame.height)

self.frame = NSRect(origin: frame.origin, size: newSize)
}
}
}
// swiftlint:enable line_length
}
19 changes: 0 additions & 19 deletions TextViewPlus/NSTextView+Style.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,4 @@ extension NSTextView {

textStorage?.endEditing()
}

public var wrapsTextToHorizontalBounds: Bool {
get {
return textContainer?.widthTracksTextView ?? false
}
set {
guard let scrollView = enclosingScrollView else {
return
}

let max = CGFloat.greatestFiniteMagnitude
let width = newValue ? scrollView.contentSize.width : max
let size = NSSize(width: width, height: max)

textContainer?.containerSize = size
textContainer?.widthTracksTextView = newValue
isHorizontallyResizable = newValue == false
}
}
}
6 changes: 3 additions & 3 deletions TextViewPlus/TextViewPlus.xcconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// TextViewPlus
//
// Created by Matt Massicotte on 2020-01-03.
// Copyright © 2020 ChimeHq. All rights reserved.
// Copyright © 2020 Chime Systems Inc. All rights reserved.
//

// Configuration settings file format documentation can be found at:
Expand All @@ -12,8 +12,8 @@
PRODUCT_NAME = TextViewPlus
PRODUCT_BUNDLE_IDENTIFIER = com.chimehq.TextViewPlus
PRODUCT_MODULE_NAME = TextViewPlus
CURRENT_PROJECT_VERSION = 4
MARKETING_VERSION = 1.0.2
CURRENT_PROJECT_VERSION = 5
MARKETING_VERSION = 1.0.3

INFOPLIST_FILE = TextViewPlus/Info.plist
FRAMEWORK_SEARCH_PATHS = $(PROJECT_DIR)/Carthage/Build/Mac $(PROJECT_DIR)/Carthage/Build/Mac/Static
Expand Down

0 comments on commit bdb89fc

Please sign in to comment.