Skip to content

Instantly share code, notes, and snippets.

@maniak-dobrii
Created September 25, 2014 13:02
Show Gist options
  • Save maniak-dobrii/5239b3a1bd313114c3e1 to your computer and use it in GitHub Desktop.
Save maniak-dobrii/5239b3a1bd313114c3e1 to your computer and use it in GitHub Desktop.
Get focused (closest to the picker's vertical center) row in UIPickerView
/**
* Returns focused (closest to the picker's vertical center) row.
*
* @param picker picker which rows should be inspected
* @param row center row to search around (row +- some_value) will be evaluated
* @param component component in picker to be inspected
*
* @note This approach requires use of -pickerView:viewForRow:forComponent:reusingView: for row creation, if you
* only use -pickerView:titleForRow:forComponent:, it won't be able to get views via -viewForRow:forComponent:
* and inspect them.
* This method should be called when all the views for rows are loaded, i.e. if you call it before you return
* a view (say, in -pickerView:titleForRow:forComponent:) it can fail and return -1.
*
* @return Focused row or -1 if it can not find it.
*/
- (NSInteger)pickerView:(UIPickerView *)picker focusedRowAroundRow:(NSInteger)row inComponent:(NSInteger)component
{
NSInteger dispersion = 20; // row +- dispersion
NSInteger fromRow = row - dispersion;
NSInteger toRow = row + dispersion;
NSInteger numberOfRows = [picker numberOfRowsInComponent:component];
if(fromRow < 0) fromRow = 0;
if(toRow >= numberOfRows) toRow = numberOfRows - 1;
NSInteger currentSelectedRow = -1;
UIView *currentSelectedRowPretendentView = nil;
CGFloat minDY = CGFLOAT_MAX;
CGFloat dy = 0;
UIView *currentView = nil;
CGPoint pickerBoundsCenter = CGPointMake(CGRectGetMidX(picker.bounds), CGRectGetMidY(picker.bounds));
// get vertically center-most view
for(NSInteger irow = fromRow; irow <= toRow; irow++)
{
currentView = [picker viewForRow:irow forComponent:component];
if(currentView)
{
CGPoint centerInPicker = [currentView convertPoint:CGPointMake(CGRectGetMidX(currentView.bounds),
CGRectGetMidY(currentView.bounds))
toView:picker];
dy = fabs(centerInPicker.y - pickerBoundsCenter.y);
if(dy < minDY)
{
minDY = dy;
currentSelectedRow = irow;
currentSelectedRowPretendentView = currentView;
}
}
}
// if pretendent's row dy is bigger then it's height it should not be selected
if(minDY > currentSelectedRowPretendentView.bounds.size.height)
{
currentSelectedRow = -1;
}
return currentSelectedRow;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment