Re: Merging scrolling/clipping with NSStackView
Re: Merging scrolling/clipping with NSStackView
- Subject: Re: Merging scrolling/clipping with NSStackView
- From: Jonathan Mitchell <email@hidden>
- Date: Fri, 20 Jan 2017 10:47:14 +0000
> On 19 Jan 2017, at 18:25, Quincey Morris <email@hidden> wrote:
>
> On Jan 19, 2017, at 06:39 , Daryle Walker <email@hidden> wrote:
>>
>> The inner views should be as tall as they need to be.
>
> I don’t understand this part. How tall is that?
>
> I assume you mean that you want the text and table views to be tall enough to show all of their contents, then stacked together and wrapped in a single scroller. Conceptually that makes sense, but:
>
> 1. The stack view is going to size itself, in the absence of explicit constraints, based on the *intrinsic* sizes of the stacked views, and neither text nor table view is going to report its full height as its intrinsic height. Re-working them to provide that information is going to be very, very painful.
>
Everything Quincey says is right.
No surprise there then.
However, subclassing NSTableView and NSTextView to provide intrinsicContentSize does not have to be awful for a simple scenario (though these sort of things can descend into awfulness sometimes…)
Obviously you need to obtain raw NSTableView and NSTextView instances sans NSScollView containers.
NSTableView might go something like this:
@implementation TSTableView
- (NSSize)intrinsicContentSize
{
NSSize size = [super intrinsicContentSize];
NSInteger nr = [self numberOfRows];
CGFloat rh = [self rowHeight];
CGFloat ih = [self intercellSpacing].height;
size.height = rh * nr + ih * MAX(nr, 1);
return size;
}
For textviews I do something like:
@interface TSTextView : NSTextView
// primitives
@property (assign, nonatomic) CGFloat borderOffsetX;
@property (assign, nonatomic) CGFloat borderOffsetY;
@end
@implementation TSTextView
#pragma mark -
#pragma mark Life cycle
- (instancetype)initWithFrame:(NSRect)frameRect textContainer:(nullable NSTextContainer *)container
{
self = [super initWithFrame:frameRect textContainer:container];
if (self) {
[self commonInit];
}
return self;
}
- (nullable instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (self) {
[self commonInit];
}
return self;
}
- (void)commonInit
{
_borderOffsetX = 1;
_borderOffsetY = 3;
self.usesFontPanel = NO;
self.usesFindPanel = NO;
}
#pragma mark -
#pragma mark Auto layout
- (NSSize)intrinsicContentSize
{
NSTextContainer* textContainer = [self textContainer];
NSLayoutManager* layoutManager = [self layoutManager];
[layoutManager ensureLayoutForTextContainer: textContainer];
NSSize size = [layoutManager usedRectForTextContainer: textContainer].size;
return NSMakeSize(NSViewNoInstrinsicMetric, size.height);
}
#pragma mark -
#pragma mark Accessors
- (void)setString:(NSString *)string
{
[super setString:string];
[self invalidateIntrinsicContentSize];
}
#pragma mark -
#pragma mark Text change notifications
- (void)didChangeText
{
[super didChangeText];
[self invalidateIntrinsicContentSize];
}
#pragma mark -
#pragma mark Focus ring
- (void)drawFocusRingMask
{
if (self.editable) {
NSRectFill(self.focusRingMaskBounds);
}
}
- (NSRect)focusRingMaskBounds {
NSRect r = [self bounds];
return NSMakeRect(r.origin.x - self.borderOffsetX, r.origin.y - self.borderOffsetY, r.size.width + self.borderOffsetX * 2, r.size.height + self.borderOffsetY * 2);
}
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden