3
\$\begingroup\$

I'm using HMSegmentedControl, an open-source UISegmentedControl subclass. I'm trying to react to the user tapping on the currently selected segment. HMSegmentedControl only supports reacting to a segment CHANGE, with either UIControlEventValueChanged or a block that executes when the index is changed. I need to react to the currently selected segment in order to present a drop-down menu. Here is what I've done so far:

-(void)segmentedControlValueChanged:(HMSegmentedControl *)control { CGFloat midX = self.view.frame.size.width / 2 - _filterView.frame.size.width / 2; _filterView.frame = CGRectMake(midX, -_filterView.frame.size.height+64, _filterView.frame.size.width, _filterView.frame.size.height); _filterView.hidden = YES; _filterBackgroundView.alpha = 0.0f; _filterBackgroundView.hidden = YES; } -(void)segmentedControlTouchUpInside:(UIGestureRecognizer *)gr { if(!_filterView) { _filterView = (HomeFilterView *)[[NSBundle mainBundle] loadNibNamed:@"HomeFilterView" owner:self options:nil].firstObject; CGFloat midX = self.view.frame.size.width / 2 - _filterView.frame.size.width / 2; _filterView.frame = CGRectMake(midX, -_filterView.frame.size.height+64, _filterView.frame.size.width, _filterView.frame.size.height); _filterView.delegate = self; [self.view insertSubview:_filterView belowSubview:self.segmentedControl]; } if(!_filterBackgroundView) { _filterBackgroundView = [[UIView alloc] initWithFrame:self.view.bounds]; _filterBackgroundView.backgroundColor = [UIColor blackColor]; _filterBackgroundView.alpha = 0.0f; [self.view insertSubview:_filterBackgroundView belowSubview:_filterView]; } _filterView.hidden = NO; _filterBackgroundView.hidden = NO; [UIView animateWithDuration:0.5f delay:0.0f usingSpringWithDamping:0.55f initialSpringVelocity:0.0f options:UIViewAnimationOptionCurveLinear animations:^{ CGFloat midX = self.view.frame.size.width / 2 - _filterView.frame.size.width / 2; CGFloat y = self.segmentedControl.frame.size.height + self.segmentedControl.frame.origin.y; _filterView.frame = CGRectMake(midX, y-70, _filterView.frame.size.width, _filterView.frame.size.height); } completion:^(BOOL finished) { }]; [UIView animateWithDuration:0.25f animations:^{ _filterBackgroundView.alpha = 0.5f; } completion:^(BOOL finished) { }]; } 

I added a tap gesture recognizer to the segmented control. So, if a user selects the current segment, only segmentedControlTouchUpInside: will be fired. If a user selected a different segment, segmentedControlTouchUpInside: is fired, followed by segmentedControlValueChanged:. I'm relying on the segmentedControlValueChanged: method to be called after the gesture-recognizer method, and essentially "undo" the adding of the drop-down to the UI.

This is the only way I could figure out to handle the tapping of the current segment. It seems to accomplish what I'm going for in the UI, but can anyone think of a better way of doing this? Is this safe to do?

\$\endgroup\$

    1 Answer 1

    4
    \$\begingroup\$

    You can fork the control and do a tiny modification to the code to do what you need.

    In touchesEnded:withEvent:, you need to modify this line so it wouldn't check if the tapped segment is the currently selected segment:

     if (segment < sectionsCount) 
    \$\endgroup\$
    2
    • \$\begingroup\$Hey thanks for your response! Yes I actually found this line. I'm kinda unfamiliar with forking though. If I have the control integrated into my project via Cocoapods, will I be able to keep it that way if I fork it?\$\endgroup\$
      – hgwhittle
      CommentedJan 5, 2015 at 14:19
    • \$\begingroup\$I figured it out. This SO question helped me integrate the forked repo via Cocoapods. stackoverflow.com/questions/20936885/cocoapods-and-github-forks\$\endgroup\$
      – hgwhittle
      CommentedJan 5, 2015 at 14:39

    Start asking to get answers

    Find the answer to your question by asking.

    Ask question

    Explore related questions

    See similar questions with these tags.