Skip to content

Commit f564e8d

Browse files
authored
Merge pull request #21 from TimOliver/polish-nil-items-pr
Polished PR that fixed deadlocking and crashing with items
2 parents f3e1348 + 55b0bff commit f564e8d

10 files changed

Lines changed: 317 additions & 127 deletions

File tree

CHANGELOG.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,24 @@
11
x.y.z Release Notes (yyyy-MM-dd)
22
=============================================================
33

4+
### Enhancements
5+
6+
* All `add` APIs have had `new` removed from them for more succinct naming.
7+
* Most Swift annotated methods have been renamed to match `UISegmentedControl` more closely.
8+
49
### Added
510

611
* Support for iOS 9.
12+
* A new method called `setSelectedSegmentIndex(_:animated:)` to allow animated transitions of the thumb.
713

814
### Fixed
915

10-
* A bug where creating instances with `init(items:)` would yield no visible items.
11-
* A bug where the tint color of the reversible arrow icon wouldn't update properly.
16+
* Creating instances with `init(items:)` was yielding no visible items.
17+
* Tint color of the reversible arrow icon wasn't updating properly.
18+
* A deadlock was occurring when creating an instance with no items initially, and adding items later.
19+
* A crash was occurring when trying to insert new items with invalid index numbers.
20+
* Removed trailing separators when appending items with using `insert` functions.
21+
* If touch events were canceled while tapping down on the control, UI state wasn't being restored to an untapped state.
1222

1323
1.0.1 Release Notes (2019-09-24)
1424
=============================================================

README.md

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,58 @@ As part of the visual improvements featured in iOS 13, `UISegmentedControl` was
2929

3030
`TOSegmentedControl` has been written to follow the interface of `UISegmentedControl` as closely as possible. This should make it very intuitive to work with.
3131

32+
## Swift
33+
34+
In Swift, the class is renamed to `SegmentedControl`. Creating a new instance is very similar to `UISegmentedControl`.
35+
3236
```Swift
3337

34-
let segmentedControl = SegmentedControl(items: ["First", "Second", "Third"])
38+
// Create a new instance
39+
let segmentedControl = SegmentedControl(items: )
40+
41+
// Add a closure that will be called each time the selected segment changes
3542
segmentedControlsegmentTappedHandler = { segmentIndex, reversed in
3643
print("Segment \(segmentIndex) was tapped!")
3744
}
45+
46+
// Add a new item to the end
47+
segmentedControl.addSegment(withTitle: "Fourth")
48+
49+
// Insert a new item at the beginning
50+
segmentedControl.insertSegment(withTitle: "Zero", at: 0)
51+
52+
// Remove all segments
53+
segmentedControl.removeAllSegments()
54+
3855
```
3956

40-
## System Requirements
41-
iOS 10.0 or above
57+
## Objective-C
58+
59+
```objc
60+
61+
NSArray *items = @[@"First", @"Second", @"Third"];
62+
63+
// Create a new instance
64+
TOSegmentedControl *segmentedControl = [[TOSegmentedControl alloc] initWithItems:items]];
65+
66+
// Add a block that will be called each time the selected segment changes
67+
segmentedControl.segmentTappedHandler = ^(NSInteger index, BOOL reversed) {
68+
NSLog(@"Segment %d was tapped!", index);
69+
};
70+
71+
// Add a new item to the end
72+
[segmentedControl addSegmentWithTitle:@"Fourth"];
73+
74+
// Insert a new item at the beginning
75+
[segmentedControl insertSegmentWithTitle:@"Zero" atIndex:0];
76+
77+
// Remove all segments
78+
[segmentedControl removeAllSegments];
79+
```
80+
81+
82+
# System Requirements
83+
iOS 9.0 or above
4284
4385
# Installation
4486

TOSegmentedControl/Private/TOSegmentedControlSegment.h

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222

2323
#import <Foundation/Foundation.h>
2424

25-
@class UIColor;
2625
@class UIView;
2726
@class UIImage;
2827
@class UIImageView;
@@ -68,33 +67,33 @@ NS_ASSUME_NONNULL_BEGIN
6867
/** If the item is reversible, the subsequent arrow image view. */
6968
@property (nonatomic, nullable, readonly) UIView *arrowView;
7069

71-
// Create an array of objects given an array of strings and images
70+
/// Create an array of objects given an array of strings and images
7271
+ (NSArray *)segmentsWithObjects:(NSArray *)objects
7372
forSegmentedControl:(TOSegmentedControl *)segmentedControl;;
7473

75-
// Create a non-reversible item from this class
74+
/// Create a non-reversible item from this class
7675
- (nullable instancetype)initWithObject:(id)object
7776
forSegmentedControl:(TOSegmentedControl *)segmentedControl;
7877
- (instancetype)initWithTitle:(NSString *)title
7978
forSegmentedControl:(TOSegmentedControl *)segmentedControl;
8079
- (instancetype)initWithImage:(UIImage *)image
8180
forSegmentedControl:(TOSegmentedControl *)segmentedControl;
8281

83-
// Create a potentially reversible item from this class
82+
/// Create a potentially reversible item from this class
8483
- (instancetype)initWithTitle:(NSString *)title
8584
reversible:(BOOL)reversible
8685
forSegmentedControl:(TOSegmentedControl *)segmentedControl;
8786
- (instancetype)initWithImage:(UIImage *)image
8887
reversible:(BOOL)reversible
8988
forSegmentedControl:(TOSegmentedControl *)segmentedControl ;
9089

91-
// If the item is reversible, flip the direction
90+
/// If the item is reversible, flip the direction
9291
- (void)toggleDirection;
9392

94-
// Re-synchronize the item view when the segmented control style changes
93+
/// Re-synchronize the item view when the segmented control style changes
9594
- (void)refreshItemView;
9695

97-
// Rotates the arrow image view to 180 degrees and back again
96+
/// Rotates the arrow image view to 180 degrees and back again
9897
- (void)setArrowImageReversed:(BOOL)reversed;
9998

10099
@end

TOSegmentedControl/TOSegmentedControl.h

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ IB_DESIGNABLE @interface TOSegmentedControl : UIControl
104104
@param image The image to set.
105105
@param index The index of the segment to set.
106106
*/
107-
- (void)setImage:(UIImage *)image forSegmentAtIndex:(NSInteger)index NS_SWIFT_NAME(set(_:for:));
107+
- (void)setImage:(UIImage *)image forSegmentAtIndex:(NSInteger)index NS_SWIFT_NAME(set(_:forSegmentAt:));
108108

109109
/**
110110
Replaces the content of an existing segment with a new image,
@@ -115,23 +115,23 @@ IB_DESIGNABLE @interface TOSegmentedControl : UIControl
115115
@param index The index of the segment to set.
116116
*/
117117
- (void)setImage:(UIImage *)image reversible:(BOOL)reversible
118-
forSegmentAtIndex:(NSInteger)index NS_SWIFT_NAME(set(_:reversible:for:));
118+
forSegmentAtIndex:(NSInteger)index NS_SWIFT_NAME(set(_:reversible:forSegmentAt:));
119119

120120
/**
121121
Returns the image that was assigned to a specific segment.
122122
Will return nil if the content at that segment is not an image.
123123
124124
@param index The index at which the image is located.
125125
*/
126-
- (nullable UIImage *)imageForSegmentAtIndex:(NSInteger)index NS_SWIFT_NAME(image(for:));
126+
- (nullable UIImage *)imageForSegmentAtIndex:(NSInteger)index NS_SWIFT_NAME(image(forSegmentAt:));
127127

128128
/**
129129
Sets the content of a given segment to a text label.
130130
131131
@param title The text to display at the segment.
132132
@param index The index of the segment to set.
133133
*/
134-
- (void)setTitle:(NSString *)title forSegmentAtIndex:(NSInteger)index NS_SWIFT_NAME(set(_:for:));
134+
- (void)setTitle:(NSString *)title forSegmentAtIndex:(NSInteger)index NS_SWIFT_NAME(set(_:forSegmentAt:));
135135

136136
/**
137137
Sets the content of a given segment to a text label, and
@@ -142,53 +142,53 @@ IB_DESIGNABLE @interface TOSegmentedControl : UIControl
142142
@param index The index of the segment to set.
143143
*/
144144
- (void)setTitle:(NSString *)title reversible:(BOOL)reversible
145-
forSegmentAtIndex:(NSInteger)index NS_SWIFT_NAME(set(_:reversible:for:));
145+
forSegmentAtIndex:(NSInteger)index NS_SWIFT_NAME(set(_:reversible:forSegmentAt:));
146146

147147
/**
148148
Returns the string of the title that was assigned to a specific segment.
149149
Will return nil if the content at that segment is not a string.
150150
151151
@param index The index at which the image is located.
152152
*/
153-
- (nullable NSString *)titleForSegmentAtIndex:(NSInteger)index NS_SWIFT_NAME(title(for:));
153+
- (nullable NSString *)titleForSegmentAtIndex:(NSInteger)index NS_SWIFT_NAME(titleForSegment(for:));
154154

155155
/**
156156
Adds a new text segment to the end of the list.
157157
158158
@param title The title of the new item.
159159
*/
160-
- (void)addNewSegmentWithTitle:(NSString *)title NS_SWIFT_NAME(addSegment(with:));
160+
- (void)addSegmentWithTitle:(NSString *)title NS_SWIFT_NAME(addSegment(withTitle:));
161161

162162
/**
163163
Adds a new text segment to the end of the list, and optionally makes it reversible.
164164
165165
@param title The title of the new item.
166166
@param reversible Whether the item is reversible or not.
167167
*/
168-
- (void)addNewSegmentWithTitle:(NSString *)title reversible:(BOOL)reversible NS_SWIFT_NAME(addSegment(with:reversible:));
168+
- (void)addSegmentWithTitle:(NSString *)title reversible:(BOOL)reversible NS_SWIFT_NAME(addSegment(withTitle:reversible:));
169169

170170
/**
171171
Adds a new image segment to the end of the list.
172172
173173
@param image The image of the new item.
174174
*/
175-
- (void)addNewSegmentWithImage:(UIImage *)image NS_SWIFT_NAME(addSegment(with:));
175+
- (void)addSegmentWithImage:(UIImage *)image NS_SWIFT_NAME(addSegment(with:));
176176

177177
/**
178178
Adds a new image segment to the end of the list, and optionally makes it reversible.
179179
180180
@param image The image of the new item.
181181
@param reversible Whether the item is reversible or not.
182182
*/
183-
- (void)addNewSegmentWithImage:(UIImage *)image reversible:(BOOL)reversible NS_SWIFT_NAME(addSegment(with:reversible:));
183+
- (void)addSegmentWithImage:(UIImage *)image reversible:(BOOL)reversible NS_SWIFT_NAME(addSegment(with:reversible:));
184184

185185
/**
186186
Inserts a new image segment at the specified index.
187187
188188
@param image The image to set.
189189
@param index The index of the segment to which the image will be set.
190190
*/
191-
- (void)insertSegmentWithImage:(UIImage *)image atIndex:(NSInteger)index NS_SWIFT_NAME(insertSegment(_:at:));
191+
- (void)insertSegmentWithImage:(UIImage *)image atIndex:(NSInteger)index NS_SWIFT_NAME(insertSegment(with:at:));
192192

193193
/**
194194
Inserts a new image segment at the specified segment index, and optionally makes it reversible.
@@ -198,15 +198,15 @@ IB_DESIGNABLE @interface TOSegmentedControl : UIControl
198198
@param index The index of the segment to which the image will be set.
199199
*/
200200
- (void)insertSegmentWithImage:(UIImage *)image reversible:(BOOL)reversible
201-
atIndex:(NSInteger)index NS_SWIFT_NAME(insertSegment(_:reversible:at:));
201+
atIndex:(NSInteger)index NS_SWIFT_NAME(insertSegment(with:reversible:at:));
202202

203203
/**
204204
Inserts a new title segment at the specified index.
205205
206206
@param title The title to set.
207207
@param index The index of the segment to which the image will be set.
208208
*/
209-
- (void)insertSegmentWithTitle:(NSString *)title atIndex:(NSInteger)index NS_SWIFT_NAME(insertSegment(_:at:));
209+
- (void)insertSegmentWithTitle:(NSString *)title atIndex:(NSInteger)index NS_SWIFT_NAME(insertSegment(withTitle:at:));
210210

211211
/**
212212
Inserts a new title segment at the specified index, and optionally makes it reversible.
@@ -216,7 +216,7 @@ IB_DESIGNABLE @interface TOSegmentedControl : UIControl
216216
@param index The index of the segment to which the image will be set.
217217
*/
218218
- (void)insertSegmentWithTitle:(NSString *)title reversible:(BOOL)reversible
219-
atIndex:(NSInteger)index NS_SWIFT_NAME(insertSegment(_:reversible:at:));
219+
atIndex:(NSInteger)index NS_SWIFT_NAME(insertSegment(withTitle:reversible:at:));
220220

221221
/**
222222
Remove the last segment in the list
@@ -241,37 +241,37 @@ IB_DESIGNABLE @interface TOSegmentedControl : UIControl
241241
@param enabled Whether the segment is enabled or not.
242242
@param index The specific index to enable/disable.
243243
*/
244-
- (void)setEnabled:(BOOL)enabled forSegmentAtIndex:(NSInteger)index NS_SWIFT_NAME(setEnabled(_:at:));
244+
- (void)setEnabled:(BOOL)enabled forSegmentAtIndex:(NSInteger)index NS_SWIFT_NAME(setEnabled(_:forSegmentAt:));
245245

246246
/**
247247
Returns whether the segment at the specified index is currently enabled or not.
248248
249249
@param index The index to check.
250250
*/
251-
- (BOOL)isEnabledForSegmentAtIndex:(NSInteger)index NS_SWIFT_NAME(isEnabled(at:));
251+
- (BOOL)isEnabledForSegmentAtIndex:(NSInteger)index NS_SWIFT_NAME(isEnabledForSegment(at:));
252252

253253
/**
254254
Sets whether a specific segment is currently reversible or not.
255255
256256
@param reversible Whether the segment is reversible or not.
257257
@param index The specific index to enable/disable.
258258
*/
259-
- (void)setReversible:(BOOL)reversible forSegmentAtIndex:(NSInteger)index NS_SWIFT_NAME(setReversible(_:at:));
259+
- (void)setReversible:(BOOL)reversible forSegmentAtIndex:(NSInteger)index NS_SWIFT_NAME(setReversible(_:forSegmentAt:));
260260

261261
/**
262262
Returns whether the segment at the specified index is reversible or not.
263263
264264
@param index The index to check.
265265
*/
266-
- (BOOL)isReversibleForSegmentAtIndex:(NSInteger)index NS_SWIFT_NAME(isReversible(at:));
266+
- (BOOL)isReversibleForSegmentAtIndex:(NSInteger)index NS_SWIFT_NAME(isReversibleForSegment(at:));
267267

268268
/**
269269
Sets whether a specific segment is currently in a reversed state or not.
270270
271271
@param reversed Whether the segment is currently reversed or not.
272272
@param index The specific index to enable/disable.
273273
*/
274-
- (void)setReversed:(BOOL)reversed forSegmentAtIndex:(NSInteger)index NS_SWIFT_NAME(setReversed(_:at:));
274+
- (void)setReversed:(BOOL)reversed forSegmentAtIndex:(NSInteger)index NS_SWIFT_NAME(setReversed(_:forSegmentAt:));
275275

276276
/**
277277
Returns whether the segment at the specified index is currently reversed or not.
@@ -280,6 +280,14 @@ IB_DESIGNABLE @interface TOSegmentedControl : UIControl
280280
*/
281281
- (BOOL)isReversedForSegmentAtIndex:(NSInteger)index NS_SWIFT_NAME(isReversed(at:));
282282

283+
/**
284+
Sets which segment is currently selected, and optionally play an animation during the transition.
285+
286+
@param selectedSegmentIndex The index of the segment to select.
287+
@param animated Whether the transition to the newly selected index is animated or not.
288+
*/
289+
- (void)setSelectedSegmentIndex:(NSInteger)selectedSegmentIndex animated:(BOOL)animated NS_SWIFT_NAME(setSelectedSegmentIndex(_:animated:));
290+
283291
@end
284292

285293
NS_ASSUME_NONNULL_END

0 commit comments

Comments
 (0)