rs / sdsegmentedcontrol Goto Github PK
View Code? Open in Web Editor NEWA drop-in remplacement for UISegmentedControl that mimic iOS 6 AppStore tab controls
License: MIT License
A drop-in remplacement for UISegmentedControl that mimic iOS 6 AppStore tab controls
License: MIT License
It is not entirely clear to me how SDSegmentedControl's width is setup. I dropped an UISegmentedControl to iPhone sized view which is used in an universal app and changed it class to be SDSegmentedControl, then in viewDidLoad I add various segments by '- insertSegmentWithTitle:atIndex:animated:'. At the end segmented control's view is way larger than expected.
How to make it respect sizing and auto–resizing specified in xib, so that users would scroll horizontally to tap on additional segments please?
Thanks.
Any chance to have the controller responding to tintColorDidChange (like the UISegmentedControl does)?
After performing an animation using auto layout constraints, segment control labels misplaces its positions.
Label frame moves down visually beyond the segment control bounds.
According to the example I created a sample project in swift targeting iOS 8.1 but it didn't work out as expected. I couldn't get the sample control to be visible even though view debugging showed the view does exist. There must be something wrong with the default appearance...
I have two view controller that is to be switched by the SegmentControl, so for the 2nd VC I need to set the selected index to be the 2nd item,
and when I do that in NIB, it crashes
'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: selectedSegmentIndex < (NSInteger)self._items.count'
because self._items is null when this is called.
NSParameterAssert(selectedSegmentIndex < (NSInteger)self._items.count);
and if set "selectedIndex" in viewDidLoad code, then it doesn't show the arrow correctly, the title highlight animate to the right selection, but arrow remains unchanged..
net net, I cannot set the initial selectedIndex to anything other than 1
What happens is that when we remove a segment which is selected, the application breaks.
When disabling a segment:
[self.typeSegmentedControl setEnabled:NO forSegmentAtIndex:PlaySegmentIndex];
Crashes with:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 1 beyond bounds for empty array'
it appears black (because when it reaches drawRect self.backgroundColor is nil for some reasons).
even changing it from the uiappeareance protocol doesn't make any difference.
it looks like this a0ff092 doesn't work on iOS6 when compiled with the new sdk (xcode 5).
Buttons are not centred correctly or the stainView isn't...
It is highly noticeable when changing the font of the buttons to a smaller point size, then you can also notice that the button items horizontal spacing doesn't take into account the real size of the button
Hi all, can I center selected segment programmatically?
For example, after I set Selected Index, can I center selected segment into scrollable nav bar?
[self.segmentedControl setSelectedSegmentIndex:5];
???
Thanks
Luca
Is there a way to set the buttons within a scroll view, so that more than 4 or 5 items can be added without things getting cramped?
There is a similar library here - https://github.com/MugunthKumar/MKHorizMenuDemo - which has this ability.. but in other ways it is less appealing.
Any plans to add support for the segmented control to look nice when positioned at the bottom? I guess that the main changes would be repositioning the arrow as well as the shadows.
Hello !
My app won't build on XCode 4, because of SDSegmentedControl.m:105:45: Use of undeclared identifier 'NSFoundationVersionNumber_iOS_6_1'
NSFoundationVersionNumber_iOS_6_1 exists only on iOS 7, you should replace it with 993.00.
In an app with a UITabBar, if you switch tabs, the labels will appear misplaced when switching back.
I made a comment on issue 18, asking for it to be reopened, but I will also post it here new in case those do not get looked at. As in issue 18, I am also using SDSegmentedContol in viewForHeaderInSection; if you return the control itself as the entire view, there is no problem; but if you add it as a subview to a view (that will also contain other components) - the problem remains; specifically, when there is action on the SDSegmentedContol, I have it reload the entire tableview; SDSegmentedContol itself is a PART of the tableview in viewForHeaderInSection; viewForHeaderInSection gets called and while SDSegmentedContol does not get recreated, it gets added to the view that is returned for the header in the section. This is how I MUST do this to achieve the tableview effect that I need. So each time a 'segment' is selected, the tableview is reloaded and this control is added to the viewForHeaderInSection, and the arrow fails to animate properly - it does not move to the correct segment. If I do the same thing with a regular UISegmentedControl, it works perfectly.
and I tested my app with XCode5 beta1,below is the error info:
2013-06-13 10:58:03.867 ...... *** Assertion failure in -[SDSegmentedControl setSelectedSegmentIndex:], ...../SDSegmentedControl/SDSegmentedControl.m:269
2013-06-13 10:58:03.980 ..... *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: selectedSegmentIndex < (NSInteger)self._items.count'
after removed " NSParameterAssert(selectedSegmentIndex <(NSInteger)self._items.count);"
the error info:
* Terminating app due to uncaught exception 'NSRangeException', reason: '* -[__NSArrayM objectAtIndex:]: index 5 beyond bounds [0 .. 4]'
First off, thanks for this great control. It would be very helpful, if we could customize the titleLabel font for this control.
I'd like to have two separate color schemes for color stain and text color. Is there a way to do this in the same application? I'm able to set the new one after initializing the first, but when I try to set it back to the original scheme, nothing happens.
I get following error on iOS 7, which is working fine for iOS5,6
*** Assertion failure in -[SDSegmentedControl setSelectedSegmentIndex:]
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: selectedSegmentIndex < (NSInteger)self._items.count'
Like in subject i've two questions:
1.
How can add the CAGradientLayer (to use a gradient color)
How can i move (align to left) the StainView
Thank's
With the ValueChanged event with the action
This action is called even when the currently selected segment is touched. The usual behaviour with UISegmentedControl is that unless a different segment is touched this ValueChanged event should not occur.
Any ideas? Thanks.
Release shows version 1.0.2, and when compared with master repo it is totally different. Also the source is not updated for cocoapods too.
SDSegmentedControl manages to hard-freeze iOS (6.x), so that only a forced shutdown makes it work again. I have created a minimal example that puts the blame on a combination of arrowSize = 0.0 and adding segments at runtime. My theory is that one of the UIKit and/or CoreGraphics library functions is called with an excessive parameter (CGFLOAT_MAX anywhere?) that makes the graphics card go havoc. Here is the minimal example. Note that the simulator handles this case without problems, just the devices (tested on multiple phones and pods) hard-freeze.
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[_segmentedControl removeAllSegments];
_segmentedControl.arrowSize = 0.0;
[self performSelector:@selector(createMoreSegments:) withObject:nil afterDelay:2.0];
}
- (void)createMoreSegments:(id)sender
{
for ( int i = 0; i < 5; ++i )
{
[_segmentedControl insertSegmentWithTitle:[NSString stringWithFormat:@"Segment %u", i] atIndex:i animated:NO];
}
}
@end
For iOS < 6 shadow on the top is still there, while in iOS 6 there is no issue.
When arrowSize is 0, the base gray line below the arrow should not be drawn.
Im trying to make it look like the segment control is part of a UINavigation bar but since the arrow is clear i can still see the navigation bar bit under it, but if it were white it would look like its built into it.
The animation of the frame when autorotating is broken.
AFAIK the problem is due to all animations being removed in drawPathsFromPosition
.
Removing both lines re-enables the expected smooth transition of the frame.
However, another problem is that the animation duration is not in sync with the
rotation animation duration. Temporarily setting the proper duration in willRotateToInterfaceOrientation:duration:
and reseting it to the default in didRotateFromInterfaceOrientation
is a workaround, but I think the problem is that the animation duration is used for both the animation of the selection and the path of the whole layer. It should only be used for the selection and the layer animation should be somehow in sync with whatever animation is currently occuring, but I couldn't figure out a proper fix.
Have you got plans to add your project to CocoaPods?
It will be very useful :)
Hi, I get Crash log as below:
Crashed: com.apple.main-thread
SIGABRT ABORT at 0x00000001956cf270
raw
libsystem_kernel.dylib
__pthread_kill + 8
libsystem_c.dylib
basename
CoreGraphics
CG::Path::move_to_point(CGPoint const&, CGAffineTransform const*)
UIKit
+[UIBezierPath _continuousRoundedRectBezierPath:withRoundedCorners:cornerRadii:segments:smoothPillShapes:] +
UIKit
+[UIBezierPath _continuousRoundedRectBezierPath:withRoundedCorners:cornerRadius:segments:] +
SDSegmentedControl.m line 1316
-[SDStainView drawRect:]
I'm not sure if this the intended behavior of the segmented control, but when I place the object in a view that is embedded in a Navigation Controller, the segment titles don't show up. I discovered that if I scrolled up within the area where the title should be, the titles eventually showed up, so it seems that the titles are being incorrectly positioned.
I also tried embedding a UIView inside a container view, but I still had the same issue.
Any ideas?
segmentedViewAppearance.imageSize = CGSizeMake(128, 128);
doesn't seem to work.
_imageSize
is always 18 x 18.
Is it possible to create another tag for a new cocoapod version for testing on iOS7.
This works fine under IOS7 and lower, under IOS8 the first time we push the view containing he SDSegmentControl all is ok. the next time around (Go back to previous view and back to this view) the segmentControl looses appearance setting we push it see below code for the border color and width.
SDSegmentedControl *segmentedControlAppearance = SDSegmentedControl.appearance;
segmentedControlAppearance.backgroundColor = [UIColor colorWithHex:@"#453e34" alpha:alpha];
segmentedControlAppearance.borderColor = [UIColor whiteColor];
segmentedControlAppearance.arrowSize = 10;
segmentedControlAppearance.arrowHeightFactor = 1;
segmentedControlAppearance.arrowPosition = SDSegmentedArrowPositionTop;
segmentedControlAppearance.borderWidth = 1;
we see the black defaults being drawn in black if we are on IOS8
which is inited under commonInits as
// Init border bottom layer
[self.layer addSublayer:_borderBottomLayer = CAShapeLayer.layer];
if (!SD_IS_IOS7) {
self.borderColor = UIColor.whiteColor;
self.borderWidth = .5;
} else {
self.borderColor = UIColor.blackColor;
self.borderWidth = .25;
}
The fix I used was to directly set the color to withe and the width to 1 under this init bypassing the usage of the appearance setter.
This was the way I initially was setting in my viewDidLoad
of the view being pushed as follows
- (void)segmentControlInit {
// self.segmentControl.backgroundColor = [UIColor colorWithHex:@"#453e34" alpha:alpha];
SDSegmentedControl *segmentedControlAppearance = SDSegmentedControl.appearance;
segmentedControlAppearance.backgroundColor = [UIColor colorWithHex:@"#453e34" alpha:alpha];
segmentedControlAppearance.borderColor = [UIColor whiteColor];
segmentedControlAppearance.arrowSize = 10;
segmentedControlAppearance.arrowHeightFactor = 1;
segmentedControlAppearance.arrowPosition = SDSegmentedArrowPositionTop;
segmentedControlAppearance.borderWidth = 1;
SDSegmentView *segmenteViewAppearance = SDSegmentView.appearance;`
[segmenteViewAppearance setTitleColor:[UIColor colorWithRed:0.71 green:0.7 blue:0.7 alpha:1] forState:UIControlStateNormal];
[segmenteViewAppearance setTitleColor:[UIColor colorWithHex:@"#70ae47" alpha:1] forState:UIControlStateSelected];
segmenteViewAppearance.titleShadowOffset = CGSizeZero;
`SDStainView *stainViewAppearance = SDStainView.appearance;`
stainViewAppearance.backgroundColor = [UIColor clearColor];
stainViewAppearance.shadowColor = [UIColor colorWithHex:@"#453e34" alpha:1];
stainViewAppearance.shadowBlur = 0;
stainViewAppearance.shadowOffset = CGSizeZero;
}
After having 5 items in the Example project named 'Big Segment x' I found out the the scrolling is not correct.
Even with fewer items that result to a width bigger than the view bounds, the scrolling is not enabled, although it should have been.
I had a look at the code and it seems that the items' frames are correctly set. Could not locate the error though, most probably it is a wrong setting of the scrolling offset.
Could you please take a look at the issue?
Hello,
My segment control is made of 14 segments and I want the last one to be the first selected segment. I did so by using [segmentControl setSelectedSegmentIndex:13];
My problem is that when the view is loaded a part of the last segment is out of the borders of the view and I want it to be completely visible from the start. Can I have some help?
Hi,
do you plan to implement the image support? The UISegmentedControl can be initialised with a list of images instead of strings.
cheers
how to hide the arrow and line of bottom?
add Transparency to iOS 7 with the old design :-)
Could you do a pod trunk push
, please?
HI friend,
Its a nice control but I have a proble, my table view scrolling started jerking after I placed this control in the same page :( any idea?
For some reason, I can't find SDSegmentedControl using
pod search sdseg
When I put it in my Podfile. it comes back with:
Unable to find a pod named `SDSegmentedControl'
... when I try to install or update.
When I run SDSegmentedControl Demo, I try click Disable Segement Button, At last, The app will crash. I found this code don't check selectedSegmentIndex.
(void)setEnabled:(BOOL)enabled forSegmentAtIndex:(NSUInteger)index
{
[self segmentAtIndex:index].enabled = enabled;
if (index == self.selectedSegmentIndex)
{
self.selectedSegmentIndex = [self firstEnabledSegmentIndexNearIndex:index];
}
}
The Demo App Crash Log is:
2013-11-11 23:11:46.110 Example[70636:70b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: index >= 0 && index < self._items.count'
*** First throw call stack:
(
0 CoreFoundation 0x01b195e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x017088b6 objc_exception_throw + 44
2 CoreFoundation 0x01b19448 +[NSException raise:format:arguments:] + 136
3 Foundation 0x010dbfee -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 116
4 Example 0x0000745b -[SDSegmentedControl segmentAtIndex:] + 363
5 Example 0x00006305 -[SDSegmentedControl setEnabled:forSegmentAtIndex:] + 69
6 Example 0x000033af -[ViewController disableSegment:] + 191
7 libobjc.A.dylib 0x0171a874 -[NSObject performSelector:withObject:withObject:] + 77
8 UIKit 0x0026b0c2 -[UIApplication sendAction:to:from:forEvent:] + 108
9 UIKit 0x0026b04e -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 61
10 UIKit 0x003630c1 -[UIControl sendAction:to:forEvent:] + 66
11 UIKit 0x00363484 -[UIControl _sendActionsForEvents:withEvent:] + 577
12 UIKit 0x00362733 -[UIControl touchesEnded:withEvent:] + 641
13 UIKit 0x002a851d -[UIWindow _sendTouchesForEvent:] + 852
14 UIKit 0x002a9184 -[UIWindow sendEvent:] + 1232
15 UIKit 0x0027ce86 -[UIApplication sendEvent:] + 242
16 UIKit 0x0026718f _UIApplicationHandleEventQueue + 11421
17 CoreFoundation 0x01aa283f CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 15
18 CoreFoundation 0x01aa21cb __CFRunLoopDoSources0 + 235
19 CoreFoundation 0x01abf29e __CFRunLoopRun + 910
20 CoreFoundation 0x01abeac3 CFRunLoopRunSpecific + 467
21 CoreFoundation 0x01abe8db CFRunLoopRunInMode + 123
22 GraphicsServices 0x031689e2 GSEventRunModal + 192
23 GraphicsServices 0x03168809 GSEventRun + 104
24 UIKit 0x00269d3b UIApplicationMain + 1225
25 Example 0x000022cd main + 141
26 Example 0x00002235 start + 53
)
libc++abi.dylib: terminating with uncaught exception of type NSException
I'm not sure if it is linked to issue #44, but I have found another bug: when rotating the device when the segmented control is not visible (i.e. in another view controller) and then returning to the view controller again, the paths aren't drawn correctly.
To reproduce:
Create an empty iOS application, add SDSegmentedControl and use this as the application: didFinishLaunchingWithOptions:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
UIViewController *firstVC = [[UIViewController alloc] init];
firstVC.title = @"Segment";
UIViewController *secondVC = [[UIViewController alloc] init];
secondVC.title = @"Dummy";
SDSegmentedControl *segmentController = [[SDSegmentedControl alloc] initWithItems:@[@"1", @"2"]];
segmentController.frame = CGRectMake(0, 0, self.window.frame.size.width, segmentController.frame.size.height);
[firstVC.view addSubview:segmentController];
UITabBarController *rootController = [[UITabBarController alloc] init];
[rootController addChildViewController:firstVC];
[rootController addChildViewController:secondVC];
self.window.rootViewController = rootController;
[self.window makeKeyAndVisible];
return YES;
}
Now start the application. The following scenario works as expected:
But the following does not work as expected:
In this second case, the paths that are drawn only occupy the 320 points of the portrait mode.
I already found that it goes wrong in the function that draws the paths and only when the duration > 0. But then I got stuck trying to fix it...
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.