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

Issue when configured using auto layout and viewDidLoad #22

Closed
sguillope opened this issue Dec 5, 2013 · 8 comments
Closed

Issue when configured using auto layout and viewDidLoad #22

sguillope opened this issue Dec 5, 2013 · 8 comments

Comments

@sguillope
Copy link
Contributor

Hi,

Since the release of 1.3 and the introduction of the scrolling capability we're not able to use HMSegmentedControl in combination with auto layout's constraints.

We configure our subviews in viewDidLoad and at that time their frame is not determined yet. We use auto layout constraints to have the subviews automatically placed properly.
The problem is that when HMSegmentedControl sets the frame of self.scrollView (line 257), self.frame.size.width and self.frame.size.height are equal to 0 making the view invisible.

Here's an example of our setup:

- (void)viewDidLoad
{
  [super viewDidLoad];

  HMSegmentedControl *segmentedControl = [[HMSegmentedControl alloc] initWithSectionTitles:sectionTitles];
  segmentedControl.backgroundColor = [UIColor clearColor];
  segmentedControl.textColor = [UIColor grayColor];
  segmentedControl.font = [UIFont boldSystemFontOfSize:16.0f];

  segmentedControl.selectedTextColor = [UIColor blackColor];
  segmentedControl.selectionIndicatorHeight = 5.0f;
  segmentedControl.selectionIndicatorColor = [UIColor colorWithHex:0x00A5E4];
  segmentedControl.selectionIndicatorLocation = HMSegmentedControlSelectionIndicatorLocationDown;
  segmentedControl.selectionStyle = HMSegmentedControlSelectionStyleBox;
  segmentedControl.selectedSegmentIndex = 0;

  [self.containerView addSubview:segmentedControl];
  [self.containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-0-[segmentedControl]-0-|"
                                                                             options:0
                                                                             metrics:nil
                                                                               views:@{@"segmentedControl": segmentedControl}]];
  [self.containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[segmentedControl]-0-|"
                                                                             options:0
                                                                             metrics:nil
                                                                               views:@{@"segmentedControl": segmentedControl}]];
}

Note: self.containerView is already a subview of self.view through the storyboard

@HeshamMegid
Copy link
Owner

I believe setting the autoresizingMask for the scrollview should fix this.

Try adding this line after line 111:

self.scrollView.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth;

Let me know whether that fixes it or not as I wasn't able to reproduce your issue on my side, so it would be awesome if you could provide a sample project.

@sguillope
Copy link
Contributor Author

I've created a test project if you want to have a look at it: https://github.com/sguillope/HMSegmentedControlTest

@HeshamMegid
Copy link
Owner

Sorry it took me ages to get back to you. It has been a busy couple of weeks.

Pre version 1.3, if the frame of the control wasn't set, the width would be calculated based on the number of segments and the size of the strings inside them.

This wouldn't work with the case of the scroll view because if its width is equal to the total width of the segments then it wouldn't scroll.

According to the AutoLayout constraints you're using, the scroll view width should be set to the width of its super view, but that doesn't happen because by the time the segmented control moves to the super view, the AutoLayout constraints wouldn't have been applied yet.

The simple solution for this is to update the segmented control frame after the AutoLayout constraints have been applied:

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    self.segmentedControl.frame = self.segmentedControlWrapper.bounds;
}

@Mo7amedFouad
Copy link

I think it's better if you set the frame in viewDidLayoutSubviews to let the view stretch when you change orientation

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    self.segmentedControl.frame = self.segmentedControlWrapper.bounds;
}

@Mo7amedFouad
Copy link

Actually if you set the frame in view's ``layoutSubviews` it should work (not tested).

-(void)layoutSubviews{
    [super layoutSubviews];
    self.frame = self.bounds;
}

@HeshamMegid
Copy link
Owner

Actually, according to the View Controller Programming Guide, viewDidLayoutSubviews is the correct way to do it.

Thanks @Mo7amedFouad! :)

@sguillope
Copy link
Contributor Author

Thank you, using viewDidLayoutSubviews did work. @Mo7amedFouad suggestion did work as well. @HeshamMegid what do you think of adding it as a fix to HMSegmentedControl.m?

@HeshamMegid
Copy link
Owner

How do you see this being added to HMSegmentedControl.m? I can only imagine it being set by its super view. Tell me your thoughts.

sguillope pushed a commit to lixar/HMSegmentedControl that referenced this issue Dec 31, 2013
layoutSubviews will get called when constraints are being applied. This
ensures that the frame of the scrollview and the segments will get
updated accordingly.

Fixes HeshamMegid#22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants