UIScrollView Autolayout Masonry subview height changed - uiscrollview

[self.view addSubview:self.scrollView];
[self.scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.view.mas_top).with.offset(.0);
make.left.equalTo(self.view.mas_left).with.offset(0.0);
make.right.equalTo(self.view.mas_right).with.offset(0.0);
make.bottom.equalTo(self.view.mas_bottom).with.offset(0.0);
}];
[self.scrollView addSubview:self.contentView];
[self.contentView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.scrollView);
make.width.equalTo(self.scrollView);
}];
[self.contentView addSubview:self.cycleScrollView];
[self.cycleScrollView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.contentView.mas_top).with.offset(.0);
make.left.equalTo(self.contentView.mas_left).with.offset(0.0);
make.right.equalTo(self.contentView.mas_right).with.offset(0.0);
make.height.equalTo(#(SCREEN_WIDTH/3));
}];
[self.contentView addSubview:self.collectionView];
[self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.cycleScrollView.mas_bottom).with.offset(5.0);
make.left.equalTo(self.contentView.mas_left).with.offset(5.0);
make.right.equalTo(self.contentView.mas_right).with.offset(-5.0);
make.height.equalTo(#(self.collectionViewCellHight * number));
}];
[self.contentView addSubview:self.tableView];
[self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.collectionView.mas_bottom).with.offset(5.0);
make.left.equalTo(self.contentView.mas_left).with.offset(5.0);
make.right.equalTo(self.contentView.mas_right).with.offset(-5.0);
make.height.equalTo(#(SCREEN_WIDTH/3 * [self.categoryItems count] + HEADERVIEWHIGHT));
}];
[self.contentView mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.equalTo(self.tableView.mas_bottom).with.offset(50.0);
}];
and the Masonry warning :
Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(
"<MASLayoutConstraint:0x7f93031d8880 UITableView:0x7f930489b800.height == 415>",
"<MASLayoutConstraint:0x7f930342c990 UITableView:0x7f930489b800.height == 290>"
)
Will attempt to recover by breaking constraint
I make a contentView in scrollview and all other views in the contentView.But the collectionView and the tableView's height will change,
so the result of this goes wrong.My question is when the subview's height changed, what should I do to fix this?
Thanks you.
edit:
When the tableview's datasource changed, from 2 to 3, but the height of tableview does not show the right height.

I have not used Masonry-iOS-OSX, but as far as autolayout is concerned, don't give the height to scroll view (you are doing so when you connect scroll view with the top and bottom of super view), its height should be dependent on the inner views. Remove the top and bottom constraints of the scroll view and put align center to the super view. so that when the height of collection view changes it will change the height of the scroll view.
Hope it resolves you problem.

Related

Hidden view in NSStackView not hiding?

I have created a vertical NSStackView that contains two NSView subclasses (they are just NSViews that draw a background color). I have the stack view set to detach hidden views. I have set one of the views to be hidden.
Neither view hides in the stack view.
To make sure I'm not insane, I also set up two of the same NSViews next to each other, hiding one. Sure enough, one does hide.
The stack view's distribution is set to Fill Proportionally (not that that seems to matter).
In IB the behavior seems correct; one of the views hides.
I must be missing something incredibly obvious here, right?
In case it is relevant, the NSView subclass:
#import "ViewWithBackgroundColor.h"
#implementation ViewWithBackgroundColor
- (void)drawRect:(NSRect)dirtyRect {
[super drawRect:dirtyRect];
[self.backgroundColor set];
[NSBezierPath fillRect:dirtyRect];
if(self.bottomBorderColor != nil) {
NSBezierPath *linePath = [[NSBezierPath alloc] init];
[self.bottomBorderColor set];
linePath.lineWidth = 2.0;
[linePath moveToPoint:NSMakePoint(0, 0)];
[linePath lineToPoint:NSMakePoint(dirtyRect.size.width, 0)];
[linePath stroke];
}
}
- (NSColor *) backgroundColor {
if (_backgroundColor) {
return _backgroundColor;
} else {
return [NSColor clearColor];
}
}
#end
This looks like an issue with IB and stack view (please file a bug report if you already haven't).
To workaround it you could either:
Don't hide the button in IB, and set it to be hidden at runtime.
or
Uncheck the 'Detaches Hidden Views' stack view property in IB (visible in your screen shot), and set it at runtime with -[NSStackView setDetachesHiddenViews:].

UICollectionViewCell not clickable after i add a subview to it

I am using a collection view with custom cells. I don't know why but my cells stopped working (they don't call didSelect anymore).
Basically it's a simple cell that i'm just putting a view on top of it (addSubview).
This view contains two imageViews and two labels.
I noticed that when i don't add this view, they do call didSelect. Isn't there a way to add a view on a UITableViewCell?
This is the code i'm using to add the view:
- (void)setCellWithMediaView:(TVNCategoryWideAndTallMediaView *)mediaView {
if (self.contentView.subviews.count > 0) {
[[self.contentView.subviews lastObject] removeFromSuperview];
}
self.categoryWideAndTallMediaView = [[TVNCategoryWideAndTallMediaView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
self.categoryWideAndTallMediaView = mediaView;
[self.contentView addSubview:self.categoryWideAndTallMediaView];
self.isMediaSet = YES;
}
You can set the userInteractionEnabled property to NO for that view and subviews.
self.categoryWideAndTallMediaView.userInteractionEnabled = NO;

How to hook up UIPageControl so it scrolls up with other controls?

I places a UIScrollView inside the main UIView of my viewcontroller.
Then I added some controls at the bottom of the view and a UIPageControl near the top.
When i scroll the view, the bottom controls scroll fine but the UIPageControl remains in place, so it ends up blocking the buttons and labels at the bottom.
How do I make the UIPageControl and its views scroll up or down with the rest?
Here is what it looks like
I got it to work by:
1) Putting all views/controls inside a containerView and declaring it as a property.
2) Adding this code:
-(void)viewDidLayoutSubviews{
[super viewDidLayoutSubviews];
self.scrollView.contentSize = self.containerView.bounds.size;
}
- (void)viewDidLoad{
[super viewDidLoad];
//added with containerview from g8productions
self.containerView = [[UIView alloc] initWithFrame:CGRectMake(36, 59, 900, 1200)];
self.scrollView.translatesAutoresizingMaskIntoConstraints = NO;
[self.scrollView addSubview:self.containerView];
[self.scrollView setContentSize:self.containerView.bounds.size];
}
Now it scrolls! :)

Programmatically added subviews in table view not responding to mouse down events

I have 3 subclasses: a Block class, a Row class and a Table class. All are subclasses of NSView.
I have a Table added with IB which programmatically displays 8 rows, each of which displays 8 blocks. I overrode the mouseDown: method in Block to change the background color to red, but it doesn't work. Still if I add a block directly on top of the Table with IB it does work so I can't understand why it won't work in the first case.
Here's the implementation code for Block and Row (Table's implementation works the same way as Row's):
//block.m
- (void)drawRect:(NSRect)dirtyRect
{
[color set];
[NSBezierPath fillRect:dirtyRect];
}
-(void)mouseDown:(NSEvent *)theEvent
{
color = [NSColor redColor];
checked = YES;
[self setNeedsDisplay:YES];
}
//row.m
- (void)drawRect:(NSRect)dirtyRect
{
[[NSColor blueColor] set];
[NSBezierPath fillRect:dirtyRect];
int x;
for(x=0; x<8; x++){
int margin = x*2;
NSRect rect = NSMakeRect(0, 50*x+margin, 50, 50);
Block *block = [[Block alloc] initWithFrame:rect];
[self addSubview:block];
}
}
Are you aware that NSTableView will use NSCell objects for it's drawing, and not an NSView? If not, investigate NSCell - using that for custom drawing in an NSTable is the way to go.
I understood the problem... since the mouseDown implementation would cause the block to redraw, and so even its superview, it would call Table's drawRect: method causing it to draw new blocks on top of the old ones, and so it would seem never to change color. So I created a property for Table called isFirstAppearance initially set to YES which if YES makes the table draw the rows and sets itself to NO.

Core Animation with an NSView and subviews

I've subclassed NSView to create a 'container' view (which I've called TRTransitionView) which is being used to house two subviews. At the click of a button, I want to transition one subview out of the parent view and transition the other in, using the Core Animation transition type: kCATransitionPush. For the most part, I have this working as you'd expect (here's a basic test project I threw together).
The issue I'm seeing relates to resizing my window and then toggling between my two views. After resizing a window, my subviews will appear at seemingly random locations within my TRTransitionView. Additionally, it appears as if the TRTransitionView hasn't stretched correctly and is clipping the contents of its subviews. Ideally, I would like subviews anchored to the top-left of their parent view at all times, and to also grow to expand the size of the parent view.
The second issue relates to an NSTableView I've placed in my first subview. When my window is resized, and my TRTransitionView resizes to match its new dimensions, my TableView seems to resize its content quite awkwardly (the entire table seems to jolt around) and the newly expanded space that the table now occupies seems to 'flash' (as if in the process of being animated). Extremely difficult to describe, but is there any way to stop this?
Here's my TRTransitionView class:
-(void) awakeFromNib
{
[self setWantsLayer:YES];
[self addSubview:[self currentView]];
transition = [CATransition animation];
[transition setType:kCATransitionPush];
[transition setSubtype:kCATransitionFromLeft];
[self setAnimations: [NSDictionary dictionaryWithObject:transition forKey:#"subviews"]];
}
- (void)setCurrentView:(NSView*)newView
{
if (!currentView) {
currentView = newView;
return;
}
[[self animator] replaceSubview:currentView with:newView];
currentView = newView;
}
-(IBAction) switchToViewOne:(id)sender
{
[transition setSubtype:kCATransitionFromLeft];
[self setCurrentView:viewOne];
}
-(IBAction) switchToViewTwo:(id)sender
{
[transition setSubtype:kCATransitionFromRight];
[self setCurrentView:viewTwo];
}

Resources