Macos 如何手动告诉NSTextContainer重新计算lineFragmentRects?
在我的应用程序中,我添加了对NSTextView的支持,允许子视图自然地与文本编辑器一起工作。(例如,按“enter”键会将每个子视图放置在低于插入点的位置,并且文本环绕子视图。) 通过覆盖Macos 如何手动告诉NSTextContainer重新计算lineFragmentRects?,macos,cocoa,swift,nstextcontainer,Macos,Cocoa,Swift,Nstextcontainer,在我的应用程序中,我添加了对NSTextView的支持,允许子视图自然地与文本编辑器一起工作。(例如,按“enter”键会将每个子视图放置在低于插入点的位置,并且文本环绕子视图。) 通过覆盖lineFragmentRectForProposedRect(proposedRect:NSRect, 扫描方向:NSLineSweepDirection, movementDirection:NSLineMovementDirection, remainingRect:NSRectPointer)->NS
lineFragmentRectForProposedRect(proposedRect:NSRect,
扫描方向:NSLineSweepDirection,
movementDirection:NSLineMovementDirection,
remainingRect:NSRectPointer)->NSRect
但是,当拖动子视图或调整其大小时,需要重新计算文本中的打断以获得所需的效果。拖动或调整子视图的大小时,文本需要更新自身以环绕子视图。但是,我注意到在一行上键入会更新该行的lineFragmentRect。有没有办法在拖动子视图后立即将文本标记为“脏”文本?下面是文本容器子类的代码:
import Cocoa
class CASTextContainer: NSTextContainer {
var mainView: CASTextView = CASTextView()
var textSubviews: Array<AnyObject> {
get {
return mainView.subviews
}
}
override var simpleRectangularTextContainer: Bool {
get {
return false
}
}
func rectForActiveRange() -> NSRect {
let range = layoutManager.glyphRangeForCharacterRange(textView.selectedRange, actualCharacterRange:nil)
var rect = layoutManager.boundingRectForGlyphRange(range, inTextContainer: self)
rect = NSOffsetRect(rect, textView.textContainerOrigin.x, textView.textContainerOrigin.y)
return rect;
}
override func lineFragmentRectForProposedRect(proposedRect: NSRect,
sweepDirection: NSLineSweepDirection,
movementDirection: NSLineMovementDirection,
remainingRect: NSRectPointer) -> NSRect
{
remainingRect.initialize(NSZeroRect)
var frames: Array<NSRect> = []
if textSubviews.isEmpty {
let fullRect = NSMakeRect(0, 0, containerSize.width, containerSize.height)
return NSIntersectionRect(fullRect, proposedRect)
}
for view in textSubviews {
frames.append(view.frame)
}
// Sort the array so that the frames are ordered by increasing origin x coordinate.
let fullRect = NSMakeRect(0, 0, containerSize.width, containerSize.height)
let region = NSIntersectionRect(fullRect, proposedRect)
let sortedFrames: Array<NSRect> = sorted(frames, { (first: NSRect, second: NSRect) -> Bool in
return first.origin.x < second.origin.x
})
// Get the first rectangle height that overlaps with the text region's height.
var textDrawingRegion = NSZeroRect
var subviewFrame = NSZeroRect // Will be needed later to set remainingRect pointer.
var precedingRegion: NSRect = NSZeroRect // Hold the view frame preceding our insertion point.
for frame in sortedFrames {
if region.origin.y + NSHeight(region) >= frame.origin.y &&
region.origin.y <= frame.origin.y + NSHeight(frame)
{
if region.origin.x <= frame.origin.x {
// Calculate the distance between the preceding subview and the approaching one.
var width: CGFloat = frame.origin.x - precedingRegion.origin.x - NSWidth(precedingRegion)
textDrawingRegion.origin = region.origin
textDrawingRegion.size = NSMakeSize(width, NSHeight(region))
subviewFrame = frame
break
}
else {
precedingRegion = frame
}
}
}
if textDrawingRegion == NSZeroRect {
return region
}
else {
// Set the "break" in the text to the subview's location:
let nextRect = NSMakeRect(subviewFrame.origin.x + NSWidth(subviewFrame),
region.origin.y,
NSWidth(proposedRect),
NSHeight(proposedRect))
remainingRect.initialize(nextRect)
return textDrawingRegion
}
}
}
导入可可粉
类CASTextContainer:NSTextContainer{
var mainView:CASTextView=CASTextView()
var textSubviews:数组{
得到{
返回mainView.subview
}
}
重写变量simpleRectangularTextContainer:Bool{
得到{
返回错误
}
}
func rectforactivaterange()->NSRect{
let range=layoutManager.glyphRangeForCharacterRange(textView.selectedRange,actualCharacterRange:nil)
var rect=layoutManager.boundingrectforglyprange(范围,inTextContainer:self)
rect=NSOffsetRect(rect,textView.textContainerOrigin.x,textView.textContainerOrigin.y)
返回矩形;
}
重写函数lineFragmentRectForProposedRect(proposedRect:NSRect,
扫描方向:NSLineSweepDirection,
movementDirection:NSLineMovementDirection,
remainingRect:NSRectPointer)->NSRect
{
remainingRect.initialize(NSZeroRect)
变量帧:数组=[]
如果textSubviews.isEmpty{
设fullRect=NSMakeRect(0,0,containerSize.width,containerSize.height)
返回NSIntersectionRect(fullRect、proposedRect)
}
用于文本子视图中的视图{
frames.append(view.frame)
}
//对阵列进行排序,以便通过增加原点x坐标对帧进行排序。
设fullRect=NSMakeRect(0,0,containerSize.width,containerSize.height)
let region=NSIntersectionRect(fullRect,proposedRect)
让sortedFrames:Array=sorted(帧,{(第一个:NSRect,第二个:NSRect)->Bool-in
返回第一个.origin.x<第二个.origin.x
})
//获取与文本区域高度重叠的第一个矩形高度。
var textDrawingRegion=NSZeroRect
稍后将需要var subviewFrame=NSZeroRect//来设置remainingRect指针。
var-precingRegion:NSRect=NSZeroRect//保留插入点之前的视图框。
用于分拣帧中的帧{
如果region.origin.y+NSHeight(region)>=frame.origin.y&&
地区.起源.y