12+ (instancetype) itemWithLevelId:(NSString *)levelId sublocationId:(int32_t)sublocationId {
13 LevelInfo *item = [[LevelInfo alloc] init];
14 item.levelId = levelId;
15 item.sublocationId = sublocationId;
29- (instancetype)initWithOrigin:(CGPoint)origin
34 _defaultPosition = origin;
44 _floors = [floors copy] ?: @[];
47 if (_selectedFloorIndex < 0 || _selectedFloorIndex >= _floors.count) {
48 _selectedFloorIndex = _floors.count > 0 ? 0 : NSNotFound;
57 [
self showButtonsIfNeeded];
62 self.backgroundColor = [UIColor clearColor];
64 self.translatesAutoresizingMaskIntoConstraints = NO;
71 _tableView = [[UITableView alloc] init];
72 _tableView.delegate = self;
73 _tableView.dataSource = self;
74 _tableView.backgroundColor = [UIColor clearColor];
75 _tableView.showsVerticalScrollIndicator = NO;
76 _tableView.separatorInset = UIEdgeInsetsZero;
78 _tableView.clipsToBounds = YES;
79 _tableView.bounces = NO;
80 _tableView.directionalLayoutMargins = NSDirectionalEdgeInsetsMake(0, 0, 0, 0);
81 [
self addSubview:_tableView];
83 [_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"FloorCell"];
89 [
self showButtonsIfNeeded];
94 _topButton = [
UIButton buttonWithType:UIButtonTypeSystem];
96 [_topButton setTitle:@"▲" forState:UIControlStateNormal];
97 [_topButton addTarget:
self action:@selector(topButtonPressed) forControlEvents:UIControlEventTouchUpInside];
101 _topButton.layer.maskedCorners = kCALayerMinXMinYCorner | kCALayerMaxXMinYCorner;
102 _topButton.hidden = YES;
103 [
self addSubview:_topButton];
106 _bottomButton = [
UIButton buttonWithType:UIButtonTypeSystem];
108 [_bottomButton setTitle:@"▼" forState:UIControlStateNormal];
109 [_bottomButton addTarget:
self action:@selector(bottomButtonPressed) forControlEvents:UIControlEventTouchUpInside];
113 _bottomButton.layer.maskedCorners = kCALayerMinXMaxYCorner | kCALayerMaxXMaxYCorner;
114 _bottomButton.hidden = YES;
115 [
self addSubview:_bottomButton];
120 if (_floors.count == 0) {
122 }
else if (_floors.count == 1) {
123 _tableView.hidden = YES;
124 _topButton.hidden = YES;
125 _bottomButton.hidden = YES;
130 _tableView.hidden = NO;
131 _tableView.scrollEnabled = YES;
134 _tableView.hidden = NO;
135 _tableView.scrollEnabled = NO;
138 CGFloat x = self.defaultPosition.x;
139 CGFloat y = self.defaultPosition.y;
140 if (
_config && !UIEdgeInsetsEqualToEdgeInsets(
_config.insets, UIEdgeInsetsZero)) {
145 _tableView.frame = self.bounds;
146 [
self updateButtonsPosition];
149- (void)updateButtonsPosition {
154#pragma mark - Button Actions
156- (void)topButtonPressed {
157 NSArray<NSIndexPath *> *visiblePaths = [_tableView indexPathsForVisibleRows];
158 if (visiblePaths.count == 0)
return;
160 NSIndexPath *topPath = visiblePaths.firstObject;
161 NSInteger scrollToRow = MAX(0, topPath.row - 4);
162 NSIndexPath *indexPath = [NSIndexPath indexPathForRow:scrollToRow inSection:0];
163 [_tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
166- (void)bottomButtonPressed {
167 NSArray<NSIndexPath *> *visiblePaths = [_tableView indexPathsForVisibleRows];
168 if (visiblePaths.count == 0)
return;
170 NSIndexPath *bottomPath = visiblePaths.lastObject;
171 NSInteger scrollToRow = MIN(_floors.count - 1, bottomPath.row + 4);
172 NSIndexPath *indexPath = [NSIndexPath indexPathForRow:scrollToRow inSection:0];
173 [_tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
176#pragma mark - Button Visibility Logic
178- (void)showButtonsIfNeeded {
180 _topButton.hidden = YES;
181 _bottomButton.hidden = YES;
185 [
self updateButtonsPosition];
187 CGFloat contentOffsetY = _tableView.contentOffset.y;
188 CGFloat contentHeight = _tableView.contentSize.height;
189 CGFloat viewHeight = _tableView.bounds.size.height;
192 _topButton.hidden = (contentOffsetY <= 0);
195 CGFloat distanceFromBottom = contentHeight - contentOffsetY - viewHeight;
196 _bottomButton.hidden = (distanceFromBottom <= 0);
199#pragma mark - UITableViewDataSource & UITableViewDelegate
201- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
202 return _floors.count;
205- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
206 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"FloorCell" forIndexPath:indexPath];
207 cell.selectionStyle = UITableViewCellSelectionStyleNone;
208 cell.textLabel.textAlignment = NSTextAlignmentCenter;
210 LevelInfo *levelInfo = _floors[indexPath.row];
211 cell.textLabel.text = [
self displayStringForLevelId:levelInfo.levelId];
213 BOOL isSelected = (indexPath.row == _selectedFloorIndex);
217 cell.backgroundColor = isSelected ? accentColor : [UIColor whiteColor];
218 cell.textLabel.textColor = isSelected ? [UIColor whiteColor] : textColor;
219 cell.textLabel.font = [UIFont systemFontOfSize:kNCFloorSelectorFontSize];
224- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
225 if (_selectedFloorIndex == indexPath.row)
return;
227 _selectedFloorIndex = indexPath.row;
228 [tableView reloadData];
229 LevelInfo *levelInfo = _floors[indexPath.row];
231 if (_onSublocationSelected) {
232 _onSublocationSelected(levelInfo.sublocationId);
236- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
240- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
241 [
self showButtonsIfNeeded];
244#pragma mark - Helpers
246- (NSString *)displayStringForLevelId:(NSString *)levelId {
247 if (levelId.length < 5) {
250 return [[levelId substringToIndex:5] stringByAppendingString:@"..."];
253#pragma mark - Public Methods
262- (void)setSublocationId:(int32_t)sublocationId {
263 NSInteger newSelectedIndex = NSNotFound;
265 for (NSInteger i = 0; i < _floors.count; i++) {
267 if (info.sublocationId == sublocationId) {
268 newSelectedIndex = i;
273 if (newSelectedIndex == NSNotFound) {
277 if (_selectedFloorIndex == newSelectedIndex && _tableView) {
279 [
self showButtonsIfNeeded];
283 _selectedFloorIndex = newSelectedIndex;
288 if (_floors.count > 0) {
289 NSIndexPath *indexPath = [
NSIndexPath indexPathForRow:newSelectedIndex inSection:0];
293 atScrollPosition:UITableViewScrollPositionMiddle
297 atScrollPosition:UITableViewScrollPositionNone
302 [
self showButtonsIfNeeded];