Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Paragraph fix #134

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,81 +28,26 @@ public extension RichTextAttributeWriter {
at range: NSRange
) {
let text = richText.string

// Text view has selected text
if range.length > 0 {
return setAlignment(alignment, at: range)
}

// The cursor is at the beginning of the text
if range.location == 0 {
return setAlignment(alignment, atIndex: 0)
}

// The cursor is immediately after a newline
if let char = text.character(at: range.location - 1), char.isNewLineSeparator {
return setAlignment(alignment, atIndex: range.location)
}

// The cursor is immediately before a newline
if let char = text.character(at: range.location), char.isNewLineSeparator {
let location = UInt(range.location)
let index = text.findIndexOfCurrentParagraph(from: location)
return setAlignment(alignment, atIndex: index)
}

// The cursor is somewhere within a paragraph
let location = UInt(range.location)
let index = text.findIndexOfCurrentParagraph(from: location)
return setAlignment(alignment, atIndex: index)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is IMHO needed for proper functionality but it probably needs to tweak a bit with some symbols. I am still wrapping my head around why setting alignment on a new line separated by newLineSeparator changes alignment of previous line as well...

}
}

private extension RichTextAttributeWriter {

func setAlignment(
_ alignment: RichTextAlignment,
at range: NSRange
) {
let text = richText.string
let length = range.length
let location = range.location
let ulocation = UInt(location)
var index = text.findIndexOfCurrentParagraph(from: ulocation)
setAlignment(alignment, atIndex: index)
repeat {
let newIndex = text.findIndexOfNextParagraph(from: index)
if newIndex > index && newIndex < (location + length) {
setAlignment(alignment, atIndex: newIndex)
} else {
break
}
index = newIndex
} while true
}

func setAlignment(
_ alignment: RichTextAlignment,
atIndex index: Int
) {
guard let text = mutableRichText else { return }
let range = NSRange(location: index, length: 1)
let safeRange = safeRange(for: range, isAttributeOperation: true)
var attributes = text.attributes(at: safeRange.location, effectiveRange: nil)
let style = attributes[.paragraphStyle] as? NSMutableParagraphStyle ?? NSMutableParagraphStyle()
style.alignment = alignment.nativeAlignment
attributes[.paragraphStyle] = style
text.beginEditing()
text.setAttributes(attributes, range: safeRange)
text.fixAttributes(in: safeRange)
text.endEditing()
}

func setAlignment(
_ alignment: RichTextAlignment,
atIndex index: UInt
) {
let index = Int(index)
setAlignment(alignment, atIndex: index)
let uindex = text.findIndexOfCurrentParagraph(from: ulocation)
let index = Int(uindex)
let diff = location - index
let newLength = max(length + diff, 1)
let newRange = NSRange(location: index, length: newLength)
let alignment = alignment.nativeAlignment
let safeRange = safeRange(for: newRange)
#if os(macOS)
mutableRichText?.setAlignment(alignment, range: safeRange)
#else
let paragraph = richTextParagraphStyle(at: safeRange)
paragraph?.alignment = alignment
setRichTextAttribute(
.paragraphStyle,
to: paragraph,
at: safeRange
)
#endif
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,6 @@ public extension RichTextViewComponent {
_ alignment: RichTextAlignment
) {
if richTextAlignment == alignment { return }
if !hasTrimmedText {
let style = NSMutableParagraphStyle()
style.alignment = alignment.nativeAlignment
var attributes = richTextAttributes
attributes[.paragraphStyle] = style
typingAttributes = attributes
} else {
setRichTextAlignment(alignment, at: selectedRange)
}
setRichTextAlignment(alignment, at: selectedRange)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the issue in here is that I am testing on iOS and you on macOS. :D

This will work on macOS but not on iOS because it doesnt set the typing attributes and the behaviour of text is quite different. What I suggest is to platform-check this and use set typing attributes on non-mac platform, that way we can actually ensure it works properly and test those under both platforms.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually tested continuously in both iOS and macOS. :)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently not setting typing attributes causes obviously this:
https://github.com/danielsaidi/RichTextKit/assets/17381941/00fa4f8f-ce12-4992-9627-e09151c0e96c

I am on it, hopefully I can fix this today so lets see.

}
}
4 changes: 2 additions & 2 deletions Sources/RichTextKit/Extensions/String+Paragraph.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public extension String {
after the newline char, not the newline itself.
*/

func findIndexOfNextParagraphOrEndofCurrent(from location: UInt) -> UInt {
func findIndexOfNextParagraphOrEndOfCurrent(from location: UInt) -> UInt {
DominikBucher12 marked this conversation as resolved.
Show resolved Hide resolved
var index = location
repeat {
guard let char = character(at: index) else { break }
Expand All @@ -80,7 +80,7 @@ public extension String {
func findLengthOfCurrentParagraph(from location: UInt) -> Int {
if isEmpty { return 0 }
let startIndex = findIndexOfCurrentParagraph(from: location)
let endIndex = findIndexOfNextParagraphOrEndofCurrent(from: location)
let endIndex = findIndexOfNextParagraphOrEndOfCurrent(from: location)
return Int(endIndex)-Int(startIndex)
}

Expand Down
Loading