├── License.txt ├── UITextView+Dejal.h ├── UIButton+Dejal.h ├── UIImageView+Dejal.h ├── UITextField+Dejal.h ├── UISegmentedControl+Dejal.h ├── UIApplication+Dejal.h ├── UIColor+Dejal.h ├── UISegmentedControl+Dejal.m ├── UIImageView+Dejal.m ├── UIImage+Dejal.h ├── UIBarButtonItem+Dejal.h ├── UIView+Dejal.h ├── UILabel+Dejal.h ├── UIApplication+Dejal.m ├── UIButton+Dejal.m ├── README.markdown ├── UIBarButtonItem+Dejal.m ├── UIColor+Dejal.m ├── UITextView+Dejal.m ├── UITextField+Dejal.m ├── UIView+Dejal.m ├── UILabel+Dejal.m └── UIImage+Dejal.m /License.txt: -------------------------------------------------------------------------------- 1 | Please see the "Dejal Open Source License" web page for more information. 2 | 3 | Attribution is required, but a non-attribution license is also available. 4 | 5 | 6 | 7 | ----- 8 | 9 | Copyright (c) 2008-2015 Dejal Systems, LLC. All rights reserved. 10 | 11 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 12 | 13 | - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 14 | - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 17 | 18 | -------------------------------------------------------------------------------- /UITextView+Dejal.h: -------------------------------------------------------------------------------- 1 | // 2 | // UITextView+Dejal.h 3 | // Dejal Open Source Categories 4 | // 5 | // Created by David Sinclair on 2013-03-28. 6 | // Copyright (c) 2013-2015 Dejal Systems, LLC. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // - Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // 14 | // - Redistributions in binary form must reproduce the above copyright notice, 15 | // this list of conditions and the following disclaimer in the documentation 16 | // and/or other materials provided with the distribution. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | 30 | 31 | @interface UITextView (Dejal) 32 | 33 | - (void)dejal_setupSelectionGestures; 34 | 35 | - (NSDictionary *)dejal_selectedAttributes; 36 | 37 | @end 38 | 39 | -------------------------------------------------------------------------------- /UIButton+Dejal.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIButton+Dejal.h 3 | // Dejal Open Source Categories 4 | // 5 | // Created by David Sinclair on 2008-11-26. 6 | // Copyright (c) 2008-2015 Dejal Systems, LLC. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // - Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // 14 | // - Redistributions in binary form must reproduce the above copyright notice, 15 | // this list of conditions and the following disclaimer in the documentation 16 | // and/or other materials provided with the distribution. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | 30 | @import Foundation; 31 | 32 | 33 | @interface UIButton (Dejal) 34 | 35 | @property (nonatomic, strong, setter=dejal_setTitle:) NSString *dejal_title; 36 | 37 | - (void)dejal_addGloss; 38 | 39 | @end 40 | 41 | -------------------------------------------------------------------------------- /UIImageView+Dejal.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImageView+Dejal.h 3 | // Dejal Open Source Categories 4 | // 5 | // Created by David Sinclair on 2009-02-19. 6 | // Copyright (c) 2009-2015 Dejal Systems, LLC. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // - Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // 14 | // - Redistributions in binary form must reproduce the above copyright notice, 15 | // this list of conditions and the following disclaimer in the documentation 16 | // and/or other materials provided with the distribution. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | 30 | @import UIKit; 31 | 32 | 33 | @interface UIImageView (Dejal) 34 | 35 | + (UIImageView *)dejal_imageViewForTableCell; 36 | 37 | - (void)dejal_adjustForHighlight:(BOOL)highlighted; 38 | 39 | @end 40 | 41 | -------------------------------------------------------------------------------- /UITextField+Dejal.h: -------------------------------------------------------------------------------- 1 | // 2 | // UITextField+Dejal.h 3 | // Dejal Open Source Categories 4 | // 5 | // Created by David Sinclair on 2013-03-28. 6 | // Copyright (c) 2013-2015 Dejal Systems, LLC. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // - Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // 14 | // - Redistributions in binary form must reproduce the above copyright notice, 15 | // this list of conditions and the following disclaimer in the documentation 16 | // and/or other materials provided with the distribution. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | 30 | 31 | @interface UITextField (Dejal) 32 | 33 | @property (nonatomic, setter=dejal_setSelectedRange:) NSRange dejal_selectedRange; 34 | 35 | - (void)dejal_setupSelectionGestures; 36 | 37 | @end 38 | 39 | -------------------------------------------------------------------------------- /UISegmentedControl+Dejal.h: -------------------------------------------------------------------------------- 1 | // 2 | // UISegmentedControl+Dejal.h 3 | // Dejal Open Source Categories 4 | // 5 | // Created by David Sinclair on 2009-09-15. 6 | // Copyright (c) 2009-2015 Dejal Systems, LLC. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // - Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // 14 | // - Redistributions in binary form must reproduce the above copyright notice, 15 | // this list of conditions and the following disclaimer in the documentation 16 | // and/or other materials provided with the distribution. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | 30 | @import UIKit; 31 | 32 | 33 | @interface UISegmentedControl (Dejal) 34 | 35 | + (instancetype)dejal_segmentedControlWithItems:(NSArray *)items target:(id)target action:(SEL)action selectedIndex:(NSInteger)selectedIndex; 36 | 37 | @end 38 | 39 | -------------------------------------------------------------------------------- /UIApplication+Dejal.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIApplication+Dejal.h 3 | // Dejal Open Source Categories 4 | // 5 | // Created by David Sinclair on 2009-07-26. 6 | // Copyright (c) 2009-2015 Dejal Systems, LLC. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // - Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // 14 | // - Redistributions in binary form must reproduce the above copyright notice, 15 | // this list of conditions and the following disclaimer in the documentation 16 | // and/or other materials provided with the distribution. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // 30 | // Portions copyright Matt Gallagher 2009. All rights reserved. 31 | // 32 | // Permission is given to use this source code file, free of charge, in any 33 | // project, commercial or otherwise, entirely at your risk, with the condition 34 | // that any redistribution (in part or whole) of source code must retain 35 | // this copyright and permission notice. Attribution in compiled projects is 36 | // appreciated but not required. 37 | // 38 | 39 | 40 | @import Foundation; 41 | 42 | 43 | @interface UIApplication (Dejal) 44 | 45 | + (UIView *)dejal_firstResponder; 46 | 47 | + (UIView *)dejal_keyboardView; 48 | 49 | @end 50 | 51 | -------------------------------------------------------------------------------- /UIColor+Dejal.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+Dejal.h 3 | // Dejal Open Source Categories 4 | // 5 | // Created by David Sinclair on 2008-12-01. 6 | // Copyright (c) 2008-2015 Dejal Systems, LLC. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // - Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // 14 | // - Redistributions in binary form must reproduce the above copyright notice, 15 | // this list of conditions and the following disclaimer in the documentation 16 | // and/or other materials provided with the distribution. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | 30 | @import Foundation; 31 | 32 | 33 | @interface UIColor (Dejal) 34 | 35 | + (instancetype)dejal_promptTextColor; 36 | + (instancetype)dejal_checkmarkTextColor; 37 | + (instancetype)dejal_tableSelectionColor; 38 | + (instancetype)dejal_darkGreenColor; 39 | 40 | + (instancetype)dejal_colorWithPlatformSpecificImageNamed:(NSString *)name extension:(NSString *)extension; 41 | 42 | + (instancetype)dejal_colorWithBGRColor:(NSInteger)bgrColor; 43 | 44 | + (UIColor *)dejal_colorWithHex:(NSUInteger)hexColor alpha:(CGFloat)alpha; 45 | + (UIColor *)dejal_colorWithHexString:(NSString *)hexStr alpha:(CGFloat)alpha; 46 | + (NSUInteger)dejal_hexColorWithHexString:(NSString *)hexStr; 47 | 48 | - (UIColor *)dejal_lighterColor; 49 | - (UIColor *)dejal_darkerColor; 50 | 51 | @end 52 | 53 | -------------------------------------------------------------------------------- /UISegmentedControl+Dejal.m: -------------------------------------------------------------------------------- 1 | // 2 | // UISegmentedControl+Dejal.m 3 | // Dejal Open Source Categories 4 | // 5 | // Created by David Sinclair on 2009-09-15. 6 | // Copyright (c) 2009-2015 Dejal Systems, LLC. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // - Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // 14 | // - Redistributions in binary form must reproduce the above copyright notice, 15 | // this list of conditions and the following disclaimer in the documentation 16 | // and/or other materials provided with the distribution. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | 30 | #import "UISegmentedControl+Dejal.h" 31 | 32 | 33 | @implementation UISegmentedControl (Dejal) 34 | 35 | /** 36 | Returns a new segmented control containing the specified items, target and action, and sets the initial selected segment index. 37 | 38 | @author DJS 2009-09. 39 | @version DJS 2014-01: changed to remove the style argument, since it is obsolete. 40 | */ 41 | 42 | + (instancetype)dejal_segmentedControlWithItems:(NSArray *)items target:(id)target action:(SEL)action selectedIndex:(NSInteger)selectedIndex; 43 | { 44 | UISegmentedControl *control = [[self alloc] initWithItems:items]; 45 | 46 | control.selectedSegmentIndex = selectedIndex; 47 | 48 | [control addTarget:target action:action forControlEvents:UIControlEventValueChanged]; 49 | 50 | return control; 51 | } 52 | 53 | @end 54 | 55 | -------------------------------------------------------------------------------- /UIImageView+Dejal.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImageView+Dejal.m 3 | // Dejal Open Source Categories 4 | // 5 | // Created by David Sinclair on 2009-02-19. 6 | // Copyright (c) 2009-2015 Dejal Systems, LLC. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // - Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // 14 | // - Redistributions in binary form must reproduce the above copyright notice, 15 | // this list of conditions and the following disclaimer in the documentation 16 | // and/or other materials provided with the distribution. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | 30 | #import "UIImageView+Dejal.h" 31 | 32 | 33 | @implementation UIImageView (Dejal) 34 | 35 | + (UIImageView *)dejal_imageViewForTableCell; 36 | { 37 | UIImageView *imageView = [[self alloc] initWithFrame:CGRectZero]; 38 | 39 | imageView.backgroundColor = [UIColor whiteColor]; 40 | 41 | return imageView; 42 | } 43 | 44 | /** 45 | Adjusts the receiver when it is highlighted or dehighlighted, so it is opaque with a white background when not highlighted (for optimal drawing in tables), and clear background when highlighted. 46 | 47 | @author DJS 2009-02. 48 | */ 49 | 50 | - (void)dejal_adjustForHighlight:(BOOL)highlighted; 51 | { 52 | UIColor *backgroundColor = highlighted ? [UIColor clearColor] : [UIColor whiteColor]; 53 | 54 | self.backgroundColor = backgroundColor; 55 | 56 | [self setNeedsDisplay]; 57 | } 58 | 59 | @end 60 | 61 | -------------------------------------------------------------------------------- /UIImage+Dejal.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Dejal.h 3 | // Dejal Open Source Categories 4 | // 5 | // Created by David Sinclair on 2009-09-29. 6 | // Copyright (c) 2009-2015 Dejal Systems, LLC. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // - Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // 14 | // - Redistributions in binary form must reproduce the above copyright notice, 15 | // this list of conditions and the following disclaimer in the documentation 16 | // and/or other materials provided with the distribution. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | 30 | @import Foundation; 31 | 32 | 33 | #define DejalDegreesToRadians(degrees) ((degrees * M_PI) / 180.0) 34 | 35 | 36 | @interface UIImage (Dejal) 37 | 38 | + (UIImage *)dejal_whiteTintedImageNamed:(NSString *)name; 39 | + (UIImage *)dejal_grayTintedImageNamed:(NSString *)name; 40 | 41 | + (NSArray *)dejal_whiteTintedImages:(NSArray *)imageArray; 42 | 43 | - (UIImage *)dejal_imageWithWhiteOverlay; 44 | - (UIImage *)dejal_imageWithGrayOverlay; 45 | - (UIImage *)dejal_imageWithOverlayColor:(UIColor *)color; 46 | 47 | + (UIImage *)dejal_imageNamed:(NSString *)name withOverlayColor:(UIColor *)color; 48 | 49 | - (UIImage *)dejal_imageAspectScaledToSize:(CGSize)newSize canScaleUp:(BOOL)canScaleUp; 50 | - (UIImage *)dejal_imageAspectScaledToSize:(CGSize)newSize canScaleUp:(BOOL)canScaleUp threadSafe:(BOOL)threadSafe; 51 | 52 | - (UIImage *)dejal_imageMaskedWithCornerRadius:(CGFloat)radius; 53 | 54 | @end 55 | 56 | -------------------------------------------------------------------------------- /UIBarButtonItem+Dejal.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIBarButtonItem+Dejal.h 3 | // Dejal Open Source Categories 4 | // 5 | // Created by David Sinclair on 2009-09-15. 6 | // Copyright (c) 2009-2015 Dejal Systems, LLC. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // - Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // 14 | // - Redistributions in binary form must reproduce the above copyright notice, 15 | // this list of conditions and the following disclaimer in the documentation 16 | // and/or other materials provided with the distribution. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | 30 | @import Foundation; 31 | 32 | 33 | @interface UIBarButtonItem (Dejal) 34 | 35 | + (instancetype)dejal_barButtonWithImage:(UIImage *)image style:(UIBarButtonItemStyle)style target:(id)target action:(SEL)action; 36 | + (instancetype)dejal_barButtonWithTitle:(NSString *)title style:(UIBarButtonItemStyle)style target:(id)target action:(SEL)action; 37 | + (instancetype)dejal_barButtonSystemItem:(UIBarButtonSystemItem)systemItem target:(id)target action:(SEL)action; 38 | + (instancetype)dejal_barButtonWithCustomView:(UIView *)customView; 39 | 40 | + (instancetype)dejal_barButtonFlexibleSpace; 41 | + (instancetype)dejal_barButtonFixedSpace; 42 | + (instancetype)dejal_barButtonFixedSpaceWithWidth:(CGFloat)width; 43 | + (instancetype)dejal_barButtonNarrowSpace; 44 | 45 | + (instancetype)dejal_barButtonSegmentedControlWithItems:(NSArray *)items target:(id)target action:(SEL)action selectedIndex:(NSInteger)selectedIndex; 46 | 47 | @end 48 | 49 | -------------------------------------------------------------------------------- /UIView+Dejal.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Dejal.h 3 | // Dejal Open Source Categories 4 | // 5 | // Created by David Sinclair on 2009-02-04. 6 | // Copyright (c) 2009-2015 Dejal Systems, LLC. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // - Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // 14 | // - Redistributions in binary form must reproduce the above copyright notice, 15 | // this list of conditions and the following disclaimer in the documentation 16 | // and/or other materials provided with the distribution. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | 30 | @import UIKit; 31 | 32 | 33 | @interface UIView (Dejal) 34 | 35 | @property (nonatomic, setter=dejal_setFrameOrigin:) CGPoint dejal_frameOrigin; 36 | @property (nonatomic, setter=dejal_setFrameX:) CGFloat dejal_frameX; 37 | @property (nonatomic, setter=dejal_setFrameY:) CGFloat dejal_frameY; 38 | 39 | @property (nonatomic, setter=dejal_setBoundsSize:) CGSize dejal_boundsSize; 40 | @property (nonatomic, setter=dejal_setBoundsWidth:) CGFloat dejal_boundsWidth; 41 | @property (nonatomic, setter=dejal_setBoundsHeight:) CGFloat dejal_boundsHeight; 42 | 43 | @property (nonatomic, readonly) UIImage *dejal_imageRepresentation; 44 | 45 | - (void)dejal_setHidden:(BOOL)hide animated:(BOOL)animated; 46 | - (void)dejal_setHidden:(BOOL)hide animated:(BOOL)animated withDuration:(NSTimeInterval)duration; 47 | 48 | - (void)dejal_addToSuperview:(UIView *)view animated:(BOOL)animated; 49 | - (void)dejal_addToSuperview:(UIView *)view animated:(BOOL)animated withDuration:(NSTimeInterval)duration; 50 | 51 | - (void)dejal_removeFromSuperviewAnimated:(BOOL)animated; 52 | - (void)dejal_removeFromSuperviewAnimated:(BOOL)animated withDuration:(NSTimeInterval)duration; 53 | 54 | @end 55 | 56 | -------------------------------------------------------------------------------- /UILabel+Dejal.h: -------------------------------------------------------------------------------- 1 | // 2 | // UILabel+Dejal.h 3 | // Dejal Open Source Categories 4 | // 5 | // Created by David Sinclair on 2008-11-15. 6 | // Copyright (c) 2008-2015 Dejal Systems, LLC. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // - Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // 14 | // - Redistributions in binary form must reproduce the above copyright notice, 15 | // this list of conditions and the following disclaimer in the documentation 16 | // and/or other materials provided with the distribution. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | 30 | @import UIKit; 31 | 32 | 33 | @interface UILabel (Dejal) 34 | 35 | + (UILabel *)dejal_labelWithText:(NSString *)text font:(UIFont *)font; 36 | + (UILabel *)dejal_labelWithText:(NSString *)text font:(UIFont *)font width:(CGFloat)width height:(CGFloat)height; 37 | + (UILabel *)dejal_labelWithText:(NSString *)text font:(UIFont *)font width:(CGFloat)width lineBreakMode:(NSLineBreakMode)lineBreakMode; 38 | + (UILabel *)dejal_labelWithText:(NSString *)text font:(UIFont *)font width:(CGFloat)width height:(CGFloat)height lineBreakMode:(NSLineBreakMode)lineBreakMode; 39 | + (UILabel *)dejal_labelForPrompt:(NSString *)text withWidth:(CGFloat)width; 40 | 41 | + (UILabel *)dejal_labelForTableCellWithFont:(UIFont *)font textColor:(UIColor *)textColor highlightedTextColor:(UIColor *)highlightedTextColor; 42 | + (UILabel *)dejal_labelForTableAddRow; 43 | + (UILabel *)dejal_labelForTablePrimaryText; 44 | + (UILabel *)dejal_labelForTableSecondaryText; 45 | 46 | - (void)dejal_adjustForHighlight:(BOOL)highlighted; 47 | 48 | + (CGSize)dejal_sizeForText:(NSString *)text font:(UIFont *)font lineBreakMode:(NSLineBreakMode)lineBreakMode frameSize:(CGSize)frameSize; 49 | + (CGSize)dejal_sizeForAttributedText:(NSAttributedString *)text frameSize:(CGSize)frameSize; 50 | 51 | - (CGSize)dejal_sizeForTextWithinFrameSize:(CGSize)frameSize; 52 | - (CGSize)dejal_sizeForAttributedTextWithinFrameSize:(CGSize)frameSize; 53 | 54 | @end 55 | 56 | -------------------------------------------------------------------------------- /UIApplication+Dejal.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIApplication+Dejal.m 3 | // Dejal Open Source Categories 4 | // 5 | // Created by David Sinclair on 2009-07-26. 6 | // Copyright (c) 2009-2015 Dejal Systems, LLC. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // - Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // 14 | // - Redistributions in binary form must reproduce the above copyright notice, 15 | // this list of conditions and the following disclaimer in the documentation 16 | // and/or other materials provided with the distribution. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // 30 | // Portions copyright Matt Gallagher 2009. All rights reserved. 31 | // 32 | // Permission is given to use this source code file, free of charge, in any 33 | // project, commercial or otherwise, entirely at your risk, with the condition 34 | // that any redistribution (in part or whole) of source code must retain 35 | // this copyright and permission notice. Attribution in compiled projects is 36 | // appreciated but not required. 37 | // 38 | 39 | #import "UIApplication+Dejal.h" 40 | 41 | 42 | @implementation UIApplication (Dejal) 43 | 44 | static __weak id dejal_currentFirstResponder; 45 | 46 | /** 47 | Returns the first responder view for the application's key window. 48 | 49 | @author MG 2009-04; tweaked by DJS 2009-07. 50 | @version DJS 2015-03: changed to avoid using a private method. 51 | */ 52 | 53 | + (UIView *)dejal_firstResponder; 54 | { 55 | dejal_currentFirstResponder = nil; 56 | 57 | [[UIApplication sharedApplication] sendAction:@selector(dejal_findCurrentFirstResponder:) to:nil from:nil forEvent:nil]; 58 | 59 | return dejal_currentFirstResponder; 60 | } 61 | 62 | /** 63 | Helper for the +dejal_firstResponder method. Call that instead. 64 | 65 | @author DJS 2015-03. 66 | */ 67 | 68 | -(void)dejal_findCurrentFirstResponder:(id)sender; 69 | { 70 | dejal_currentFirstResponder = self; 71 | } 72 | 73 | /** 74 | Returns the keyboard view, if it is present. 75 | 76 | @author MG 2009-04; tweaked by DJS 2009-07. 77 | @version DJS 2012-01: changed to use UIPeripheralHostView instead of UIKeyboardView. 78 | */ 79 | 80 | + (UIView *)dejal_keyboardView; 81 | { 82 | NSArray *windows = [[self sharedApplication] windows]; 83 | 84 | for (UIWindow *window in [windows reverseObjectEnumerator]) 85 | { 86 | for (UIView *view in [window subviews]) 87 | { 88 | if (!strcmp(object_getClassName(view), "UIPeripheralHostView")) 89 | return view; 90 | } 91 | } 92 | 93 | return nil; 94 | } 95 | 96 | @end 97 | 98 | -------------------------------------------------------------------------------- /UIButton+Dejal.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIButton+Dejal.m 3 | // Dejal Open Source Categories 4 | // 5 | // Created by David Sinclair on 2008-11-26. 6 | // Copyright (c) 2008-2015 Dejal Systems, LLC. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // - Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // 14 | // - Redistributions in binary form must reproduce the above copyright notice, 15 | // this list of conditions and the following disclaimer in the documentation 16 | // and/or other materials provided with the distribution. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | 30 | #import "UIButton+Dejal.h" 31 | #import 32 | 33 | 34 | @implementation UIButton (Dejal) 35 | 36 | /** 37 | Returns the current title of the button; provided primarily for the property of the same name. 38 | 39 | @author DJS 2008-11. 40 | */ 41 | 42 | - (NSString *)dejal_title; 43 | { 44 | return [self currentTitle]; 45 | } 46 | 47 | /** 48 | Sets the button title for all control states at once. Also available via the title property. 49 | 50 | @author DJS 2008-11. 51 | */ 52 | 53 | - (void)dejal_setTitle:(NSString *)newTitle; 54 | { 55 | [self setTitle:newTitle forState:UIControlStateNormal]; 56 | [self setTitle:newTitle forState:UIControlStateHighlighted]; 57 | [self setTitle:newTitle forState:UIControlStateDisabled]; 58 | [self setTitle:newTitle forState:UIControlStateSelected]; 59 | } 60 | 61 | /** 62 | Adds a gloss layer. Note that the button type needs to be Custom for this to work. 63 | 64 | @author DJS 2013-03. 65 | */ 66 | 67 | - (void)dejal_addGloss; 68 | { 69 | CALayer *layer = self.layer; 70 | 71 | layer.masksToBounds = YES; 72 | layer.cornerRadius = 4.0; 73 | layer.borderWidth = 1.0; 74 | layer.borderColor = [UIColor colorWithWhite:0.4 alpha:0.7].CGColor; 75 | 76 | CAGradientLayer *glossLayer = [CAGradientLayer layer]; 77 | 78 | glossLayer.frame = self.layer.bounds; 79 | glossLayer.colors = @[(id)[UIColor colorWithWhite:1.0f alpha:0.2f].CGColor, 80 | (id)[UIColor colorWithWhite:1.0f alpha:0.1f].CGColor, 81 | (id)[UIColor colorWithWhite:0.75f alpha:0.1f].CGColor, 82 | (id)[UIColor colorWithWhite:0.4f alpha:0.1f].CGColor, 83 | (id)[UIColor colorWithWhite:1.0f alpha:0.2f].CGColor]; 84 | 85 | glossLayer.locations = @[@0.0, @0.5, @0.5, @0.8, @1.0]; 86 | 87 | [self.layer addSublayer:glossLayer]; 88 | 89 | [self.titleLabel setFont:[UIFont boldSystemFontOfSize:13.0]]; 90 | 91 | [self setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; 92 | [self setTitleColor:[UIColor grayColor] forState:UIControlStateHighlighted]; 93 | [self setTitleColor:[UIColor lightGrayColor] forState:UIControlStateDisabled]; 94 | } 95 | 96 | @end 97 | 98 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | DejalUIKitCategories 2 | ==================== 3 | 4 | DejalUIKitCategories is a collection of categories for UIKit on iOS, to add useful methods to classes like `UIBarButtonItem`, `UIColor`, `UIView`, and others. 5 | 6 | 7 | Donations 8 | --------- 9 | 10 | I wrote DejalUIKitCategories for my own use, but I'm making it available for the benefit of the iOS developer community. 11 | 12 | If you find it useful, a donation via PayPal (or something from my Amazon.com Wish List) would be very much appreciated. Appropriate links can be found on the Dejal Developer page: 13 | 14 | 15 | 16 | 17 | Latest Version 18 | -------------- 19 | 20 | You can find the latest version of this code via the GitHub repository: 21 | 22 | 23 | 24 | For news on updates, also check out the Dejal Developer page or the Dejal Blog filtered for Dejal categories posts: 25 | 26 | 27 | 28 | 29 | Environment & Requirements 30 | -------------------------- 31 | 32 | - iOS 8. Most methods may work in older OS versions. 33 | - Objective-C language. 34 | - ARC. 35 | 36 | 37 | Features 38 | -------- 39 | 40 | - **UIApplication+Dejal**: Adds methods to get the first responder and keyboard view of the app. 41 | - **UIBarButtonItem+Dejal**: Convenience initializers to make `UIBarButton` instances based on and image, title, system item, custom view, spacer, or segmented control. 42 | - **UIButton+Dejal**: A more convenient title property, and a method to add a gloss effect. 43 | - **UIColor+Dejal**: Convenience initializers for more standard colors, or based on a platform-specific image or hex value. 44 | - **UIImage+Dejal**: Convenience initializers for tinted images, methods to overlay images with colors, and scaling methods. 45 | - **UIImageView+Dejal**: Make a white-background image view, and adjust the background color based on the highlighted state. 46 | - **UILabel+Dejal**: Convenience initializers for labels with various text, font, width etc attributes, and sizing methods. 47 | - **UISegmentedControl+Dejal**: Convenience initializer for a segmented control with specified items, target, action, and initial selection. 48 | - **UITextField+Dejal**: A selected range property, and support for gestures to move the insertion point by swiping. 49 | - **UITextView+Dejal**: Attributes of the selection or insertion point, and support for the insertion point swiping gestures. 50 | - **UIView+Dejal**: Properties for frame and bounds components and an image representation, methods to hide, add to and remove from the superview with animation. 51 | 52 | The methods use a `dejal_` prefix to ensure uniqueness (important with categories). 53 | 54 | Some of the methods date back several years, so may be less useful nowadays, or have outdated code style. But there are still lots of gems that are used in all [Dejal](http://www.dejal.com/) apps. 55 | 56 | 57 | Usage 58 | ----- 59 | 60 | Include the desired source files in your project. 61 | 62 | 63 | License and Warranty 64 | -------------------- 65 | 66 | This code uses the standard BSD license. See the included License.txt file. Please also see the [Dejal Open Source License](http://www.dejal.com/developer/license/) web page for more information. 67 | 68 | You can use this code at no cost, with attribution. A non-attribution license is also available, for a fee. 69 | 70 | You're welcome to use it in commercial, closed-source, open source, free or any other kind of software, as long as you credit Dejal appropriately. 71 | 72 | The placement and format of the credit is up to you, but I prefer the credit to be in the software's "About" window or view, if any. Alternatively, you could put the credit in the software's documentation, or on the web page for the product. The suggested format for the attribution is: 73 | 74 | > Includes DejalUIKitCategories code from [Dejal](http://www.dejal.com/developer/). 75 | 76 | Where possible, please link the text "Dejal" to the Dejal Developer web page, or include the page's URL: . 77 | 78 | This code comes with no warranty of any kind. I hope it'll be useful to you, but I make no guarantees regarding its functionality or otherwise. 79 | 80 | 81 | Support / Contact / Bugs / Features 82 | ----------------------------------- 83 | 84 | I can't promise to answer questions about how to use the code. 85 | 86 | If you create an app that uses the code, please tell me about it. 87 | 88 | If you want to submit a feature request or bug report, please use [GitHub's issue tracker for this project](https://github.com/Dejal/DejalUIKitCategories/issues). Or preferably fork the code and implement the feature/fix yourself, then submit a pull request. 89 | 90 | Enjoy! 91 | 92 | David Sinclair 93 | Dejal Systems, LLC 94 | 95 | 96 | Contact: 97 | More open source projects: 98 | Open source announcements on Twitter: 99 | General Dejal news on Twitter: 100 | 101 | -------------------------------------------------------------------------------- /UIBarButtonItem+Dejal.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIBarButtonItem+Dejal.m 3 | // Dejal Open Source Categories 4 | // 5 | // Created by David Sinclair on 2009-09-15. 6 | // Copyright (c) 2009-2015 Dejal Systems, LLC. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // - Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // 14 | // - Redistributions in binary form must reproduce the above copyright notice, 15 | // this list of conditions and the following disclaimer in the documentation 16 | // and/or other materials provided with the distribution. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | 30 | #import "UIBarButtonItem+Dejal.h" 31 | #import "UISegmentedControl+Dejal.h" 32 | 33 | 34 | @implementation UIBarButtonItem (Dejal) 35 | 36 | /** 37 | Returns a new autoreleased bar button item containing an image. 38 | 39 | @author DJS 2009-09. 40 | */ 41 | 42 | + (instancetype)dejal_barButtonWithImage:(UIImage *)image style:(UIBarButtonItemStyle)style target:(id)target action:(SEL)action; 43 | { 44 | return [[UIBarButtonItem alloc] initWithImage:image style:style target:target action:action]; 45 | } 46 | 47 | /** 48 | Returns a new autoreleased bar button item containing a string title. Note: DejalTableViewController also has retained properties for common buttons. 49 | 50 | @author DJS 2009-09. 51 | */ 52 | 53 | + (instancetype)dejal_barButtonWithTitle:(NSString *)title style:(UIBarButtonItemStyle)style target:(id)target action:(SEL)action; 54 | { 55 | return [[UIBarButtonItem alloc] initWithTitle:title style:style target:target action:action]; 56 | } 57 | 58 | /** 59 | Returns a new autoreleased bar button item containing a standard system button. Note: DejalTableViewController also has retained properties for common buttons. 60 | 61 | @author DJS 2009-09. 62 | */ 63 | 64 | + (instancetype)dejal_barButtonSystemItem:(UIBarButtonSystemItem)systemItem target:(id)target action:(SEL)action; 65 | { 66 | return [[UIBarButtonItem alloc] initWithBarButtonSystemItem:systemItem target:target action:action]; 67 | } 68 | 69 | /** 70 | Returns a new autoreleased bar button item containing a custom view. 71 | 72 | @author DJS 2009-09. 73 | */ 74 | 75 | + (instancetype)dejal_barButtonWithCustomView:(UIView *)customView; 76 | { 77 | return [[UIBarButtonItem alloc] initWithCustomView:customView]; 78 | } 79 | 80 | 81 | // ---------------------------------------------------------------------------------------- 82 | #pragma mark - 83 | // ---------------------------------------------------------------------------------------- 84 | 85 | 86 | /** 87 | Returns a new autoreleased bar button item for flexible space. 88 | 89 | @author DJS 2009-09. 90 | */ 91 | 92 | + (instancetype)dejal_barButtonFlexibleSpace; 93 | { 94 | return [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; 95 | } 96 | 97 | /** 98 | Returns a new autoreleased bar button item for fixed space. 99 | 100 | @author DJS 2009-09. 101 | @version DJS 2012-05: changed to use a width of 15 (was defaulting to zero). 102 | */ 103 | 104 | + (instancetype)dejal_barButtonFixedSpace; 105 | { 106 | return [self dejal_barButtonFixedSpaceWithWidth:15.0]; 107 | } 108 | 109 | /** 110 | Returns a new autoreleased bar button item for fixed space, with the specified width. 111 | 112 | @author DJS 2010-04. 113 | */ 114 | 115 | + (instancetype)dejal_barButtonFixedSpaceWithWidth:(CGFloat)width; 116 | { 117 | UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil]; 118 | 119 | item.width = width; 120 | 121 | return item; 122 | } 123 | 124 | /** 125 | Returns a new autoreleased bar button item for fixed space, with a narrower width than normal. 126 | 127 | @author DJS 2010-04. 128 | @version DJS 2012-05: changed to reduce the width from 15 to 5. 129 | */ 130 | 131 | + (instancetype)dejal_barButtonNarrowSpace; 132 | { 133 | return [self dejal_barButtonFixedSpaceWithWidth:5.0]; 134 | } 135 | 136 | /** 137 | Returns a new autoreleased bar button item containing a segmented control with the specified items, target and action, and sets the initial selected segment index. A more convenient variation of the similarly-named method in the UISegmentedControl+Dejal category. 138 | 139 | @author DJS 2009-09. 140 | */ 141 | 142 | + (instancetype)dejal_barButtonSegmentedControlWithItems:(NSArray *)items target:(id)target action:(SEL)action selectedIndex:(NSInteger)selectedIndex; 143 | { 144 | return [self dejal_barButtonWithCustomView:[UISegmentedControl dejal_segmentedControlWithItems:items target:target action:action selectedIndex:selectedIndex]]; 145 | } 146 | 147 | @end 148 | 149 | -------------------------------------------------------------------------------- /UIColor+Dejal.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+Dejal.m 3 | // Dejal Open Source Categories 4 | // 5 | // Created by David Sinclair on 2008-12-01. 6 | // Copyright (c) 2008-2015 Dejal Systems, LLC. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // - Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // 14 | // - Redistributions in binary form must reproduce the above copyright notice, 15 | // this list of conditions and the following disclaimer in the documentation 16 | // and/or other materials provided with the distribution. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | 30 | #import "UIColor+Dejal.h" 31 | 32 | 33 | @implementation UIColor (Dejal) 34 | 35 | /** 36 | Returns the standard light blue color used for non-editable prompts in fields and table cells. 37 | 38 | @author DJS 2009-03. 39 | @version DJS 2011-11: changed to tweak the shade. 40 | */ 41 | 42 | + (instancetype)dejal_promptTextColor; 43 | { 44 | return [self colorWithRed:0.322 green:0.400 blue:0.569 alpha:1.000]; 45 | } 46 | 47 | /** 48 | Returns the standard blue color used for text on rows with a checkmark accessory. 49 | 50 | @author DJS 2012-01. 51 | */ 52 | 53 | + (instancetype)dejal_checkmarkTextColor; 54 | { 55 | return [UIColor colorWithRed:0.220 green:0.329 blue:0.529 alpha:1.000]; 56 | } 57 | 58 | /** 59 | Returns the standard blue color used for table cell selections. 60 | 61 | @author DJS 2009-04. 62 | */ 63 | 64 | + (instancetype)dejal_tableSelectionColor; 65 | { 66 | return [self colorWithRed:0.0 green:0.45 blue:0.93 alpha:1.0]; 67 | } 68 | 69 | /** 70 | Returns my favorite dark green color. 71 | 72 | @author DJS 2012-05. 73 | */ 74 | 75 | + (instancetype)dejal_darkGreenColor; 76 | { 77 | return [self colorWithRed:0.106 green:0.686 blue:0.204 alpha:1.0]; 78 | } 79 | 80 | /** 81 | Returns a color using an image with the specified name, including a platform component. For example, pass @"Foo" and "png" to use an image named "Foo-iPad.png" on an iPad, or "Foo-iPhone.png" on an iPhone or iPod touch. 82 | 83 | @author DJS 2011-11. 84 | */ 85 | 86 | + (instancetype)dejal_colorWithPlatformSpecificImageNamed:(NSString *)name extension:(NSString *)extension; 87 | { 88 | if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) 89 | name = [name stringByAppendingFormat:@"-iPad.%@", extension]; 90 | else 91 | name = [name stringByAppendingFormat:@"-iPhone.%@", extension]; 92 | 93 | return [UIColor colorWithPatternImage:[UIImage imageNamed:name]]; 94 | } 95 | 96 | /** 97 | Given an integer that encapsulates a BGR-format color (as used on Windows), returns the corresponding color. 98 | 99 | @author DJS 2012-07. 100 | */ 101 | 102 | + (instancetype)dejal_colorWithBGRColor:(NSInteger)bgrColor; 103 | { 104 | // BGR format: 0xFFFFFF(16777215) = white, 0 = black, (255,128,0) 0xFF8000 = blue: 105 | CGFloat red = bgrColor & 0xFF; 106 | CGFloat green = (bgrColor >> 8) & 0xFF; 107 | CGFloat blue = (bgrColor >> 16) & 0xFF; 108 | 109 | return [self colorWithRed:red / 255 green:green / 255 blue:blue / 255 alpha:1.0]; 110 | } 111 | 112 | /** 113 | Given an integer that encapsuates a RGB-format color (as used on the web), returns the corresponding color. 114 | 115 | @param hexColor An integer representation of a color, typically from a hex number or string. See the following methods. 116 | @param alpha The alpha value to use for the color, e.g. 1.0 for opaque. 117 | @returns A new color instance. 118 | 119 | @author DJS 2014-02. 120 | */ 121 | 122 | + (UIColor *)dejal_colorWithHex:(NSUInteger)hexColor alpha:(CGFloat)alpha; 123 | { 124 | CGFloat red = (hexColor >> 16) & 0xFF; 125 | CGFloat green = (hexColor >> 8) & 0xFF; 126 | CGFloat blue = hexColor & 0xFF; 127 | 128 | return [self colorWithRed:red / 255 green:green / 255 blue:blue / 255 alpha:alpha]; 129 | } 130 | 131 | /** 132 | Given a hex string representing a color, optionally with a "0x" or "#" prefix, returns the corresponding color. 133 | 134 | @param hexStr A hex string, e.g. "123ABC", "#123ABC", or "0x123ABC". 135 | @param alpha The alpha value to use for the color, e.g. 1.0 for opaque. 136 | @returns A new color instance. 137 | 138 | @author DJS 2014-02. 139 | */ 140 | 141 | + (UIColor *)dejal_colorWithHexString:(NSString *)hexStr alpha:(CGFloat)alpha; 142 | { 143 | return [self dejal_colorWithHex:[self dejal_hexColorWithHexString:hexStr] alpha:alpha]; 144 | } 145 | 146 | /** 147 | Given a hex string representing a color, optionally with a "0x" or "#" prefix, returns the corresponding integer value. 148 | 149 | @param hexStr A hex string, e.g. "123ABC", "#123ABC", or "0x123ABC". 150 | @returns The corresponding integer representation. 151 | 152 | @author DJS 2014-02. 153 | */ 154 | 155 | + (NSUInteger)dejal_hexColorWithHexString:(NSString *)hexStr; 156 | { 157 | NSUInteger hexColor = 0; 158 | NSScanner *scanner = [NSScanner scannerWithString:hexStr]; 159 | 160 | [scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString:@"#"]]; 161 | [scanner scanHexInt:(unsigned int *)&hexColor]; 162 | 163 | return hexColor; 164 | } 165 | 166 | /** 167 | Returns a lighter variation of the receiver, or the same color if the hue etc couldn't be obtained. 168 | 169 | @author DJS 2014-02. 170 | */ 171 | 172 | - (UIColor *)dejal_lighterColor; 173 | { 174 | CGFloat hue, saturation, brightness, alpha; 175 | 176 | if ([self getHue:&hue saturation:&saturation brightness:&brightness alpha:&alpha]) 177 | return [UIColor colorWithHue:hue saturation:saturation brightness:MIN(brightness * 1.25, 1.0) alpha:alpha]; 178 | else 179 | return self; 180 | } 181 | 182 | /** 183 | Returns a darker variation of the receiver, or the same color if the hue etc couldn't be obtained. 184 | 185 | @author DJS 2014-02. 186 | */ 187 | 188 | - (UIColor *)dejal_darkerColor; 189 | { 190 | CGFloat hue, saturation, brightness, alpha; 191 | 192 | if ([self getHue:&hue saturation:&saturation brightness:&brightness alpha:&alpha]) 193 | return [UIColor colorWithHue:hue saturation:saturation brightness:brightness * 0.75 alpha:alpha]; 194 | else 195 | return self; 196 | } 197 | 198 | @end 199 | 200 | -------------------------------------------------------------------------------- /UITextView+Dejal.m: -------------------------------------------------------------------------------- 1 | // 2 | // UITextView+Dejal.m 3 | // Dejal Open Source Categories 4 | // 5 | // Created by David Sinclair on 2013-03-28. 6 | // Copyright (c) 2013-2015 Dejal Systems, LLC. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // - Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // 14 | // - Redistributions in binary form must reproduce the above copyright notice, 15 | // this list of conditions and the following disclaimer in the documentation 16 | // and/or other materials provided with the distribution. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // Credit: portions based on Useful Utilities by Jonathan Hays (JH) 30 | // 31 | 32 | #import "UITextView+Dejal.h" 33 | 34 | 35 | @implementation UITextView (Dejal) 36 | 37 | /** 38 | Adds gesture recognizers to the receiver's superview to handle moving the selection via left or right swipes; one finger to move by letter, two fingers to move by word. Note that the receiver must be added to a superview before invoking this. 39 | 40 | @author DJS 2013-03, based on code by JH. 41 | */ 42 | 43 | - (void)dejal_setupSelectionGestures; 44 | { 45 | UISwipeGestureRecognizer *recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(dejal_moveLeftByLetter)]; 46 | recognizer.direction = UISwipeGestureRecognizerDirectionLeft; 47 | [self.superview addGestureRecognizer:recognizer]; 48 | 49 | recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(dejal_moveRightByLetter)]; 50 | recognizer.direction = UISwipeGestureRecognizerDirectionRight; 51 | [self.superview addGestureRecognizer:recognizer]; 52 | 53 | recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(dejal_moveLeftByWord)]; 54 | recognizer.direction = UISwipeGestureRecognizerDirectionLeft; 55 | recognizer.numberOfTouchesRequired = 2; 56 | [self.superview addGestureRecognizer:recognizer]; 57 | 58 | recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(dejal_moveRightByWord)]; 59 | recognizer.direction = UISwipeGestureRecognizerDirectionRight; 60 | recognizer.numberOfTouchesRequired = 2; 61 | [self.superview addGestureRecognizer:recognizer]; 62 | } 63 | 64 | /** 65 | Gesture handler to move the current selection right by one letter. 66 | 67 | @author DJS 2013-03, based on code by JH. 68 | */ 69 | 70 | - (void)dejal_moveLeftByLetter; 71 | { 72 | NSRange selection = self.selectedRange; 73 | NSUInteger end = selection.location + selection.length; 74 | 75 | if (!selection.length && end > 0) 76 | { 77 | end--; 78 | selection.location = end; 79 | } 80 | 81 | selection.length = 0; 82 | self.selectedRange = selection; 83 | } 84 | 85 | /** 86 | Gesture handler to move the current selection right by one letter. 87 | 88 | @author DJS 2013-03, based on code by JH. 89 | */ 90 | 91 | - (void)dejal_moveRightByLetter; 92 | { 93 | NSRange selection = self.selectedRange; 94 | NSUInteger end = selection.location + selection.length; 95 | 96 | if (!selection.length && end < self.text.length) 97 | end++; 98 | 99 | selection.location = end; 100 | selection.length = 0; 101 | self.selectedRange = selection; 102 | } 103 | 104 | /** 105 | Gesture handler to move the current selection left by one word. 106 | 107 | @author DJS 2013-03, based on code by JH. 108 | */ 109 | 110 | - (void)dejal_moveLeftByWord; 111 | { 112 | NSRange selection = self.selectedRange; 113 | NSUInteger end = selection.location + selection.length; 114 | 115 | if (selection.length) 116 | { 117 | selection.length = 0; 118 | self.selectedRange = selection; 119 | return; 120 | } 121 | 122 | NSArray *words = [self.text componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; 123 | NSScanner *scanner = [NSScanner scannerWithString:self.text]; 124 | NSUInteger begin = 0; 125 | 126 | [scanner setScanLocation:0]; 127 | 128 | for (NSString *word in words) 129 | { 130 | if ([scanner scanUpToString:word intoString:nil]) 131 | { 132 | NSUInteger scanLocation = [scanner scanLocation]; 133 | 134 | if (scanLocation < end) 135 | begin = scanLocation; 136 | } 137 | } 138 | 139 | selection.location = begin; 140 | selection.length = 0; 141 | self.selectedRange = selection; 142 | } 143 | 144 | /** 145 | Gesture handler to move the current selection right by one word. 146 | 147 | @author DJS 2013-03, based on code by JH. 148 | */ 149 | 150 | - (void)dejal_moveRightByWord; 151 | { 152 | NSRange selection = self.selectedRange; 153 | NSUInteger end = selection.location + selection.length; 154 | 155 | if (selection.length) 156 | { 157 | selection.location = end; 158 | selection.length = 0; 159 | self.selectedRange = selection; 160 | return; 161 | } 162 | 163 | NSArray *words = [self.text componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; 164 | NSScanner *scanner = [NSScanner scannerWithString:self.text]; 165 | NSUInteger location = self.text.length; 166 | 167 | [scanner setScanLocation:0]; 168 | 169 | for (NSString *word in words) 170 | { 171 | if ([scanner scanUpToString:word intoString:nil]) 172 | { 173 | NSUInteger scanLocation = [scanner scanLocation]; 174 | 175 | if (scanLocation > end) 176 | { 177 | location = scanLocation; 178 | break; 179 | } 180 | } 181 | } 182 | 183 | selection.location = location; 184 | selection.length = 0; 185 | self.selectedRange = selection; 186 | } 187 | 188 | /** 189 | Returns the attributes of the selected text or insertion point. 190 | 191 | @author DJS 2014-05. 192 | */ 193 | 194 | - (NSDictionary *)dejal_selectedAttributes; 195 | { 196 | NSAttributedString *attribText = self.attributedText; 197 | 198 | if (!attribText) 199 | { 200 | return nil; 201 | } 202 | 203 | NSRange selection = self.selectedRange; 204 | NSDictionary *attributes = nil; 205 | 206 | if (selection.location != NSNotFound && selection.location < attribText.length) 207 | { 208 | attributes = [attribText attributesAtIndex:selection.location effectiveRange:NULL]; 209 | } 210 | else 211 | { 212 | attributes = [self typingAttributes]; 213 | } 214 | 215 | return attributes; 216 | } 217 | 218 | @end 219 | 220 | -------------------------------------------------------------------------------- /UITextField+Dejal.m: -------------------------------------------------------------------------------- 1 | // 2 | // UITextField+Dejal.m 3 | // Dejal Open Source Categories 4 | // 5 | // Created by David Sinclair on 2013-03-28. 6 | // Copyright (c) 2013-2015 Dejal Systems, LLC. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // - Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // 14 | // - Redistributions in binary form must reproduce the above copyright notice, 15 | // this list of conditions and the following disclaimer in the documentation 16 | // and/or other materials provided with the distribution. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // Credit: portions based on Useful Utilities by Jonathan Hays (JH) 30 | // 31 | 32 | #import "UITextField+Dejal.h" 33 | 34 | 35 | @implementation UITextField (Dejal) 36 | 37 | /** 38 | Adds gesture recognizers to the receiver's superview to handle moving the selection via left or right swipes; one finger to move by letter, two fingers to move by word. Note that the receiver must be added to a superview before invoking this. 39 | 40 | @author DJS 2013-03, based on code by JH. 41 | */ 42 | 43 | - (void)dejal_setupSelectionGestures; 44 | { 45 | UISwipeGestureRecognizer *recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(dejal_moveLeftByLetter)]; 46 | recognizer.direction = UISwipeGestureRecognizerDirectionLeft; 47 | [self.superview addGestureRecognizer:recognizer]; 48 | 49 | recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(dejal_moveRightByLetter)]; 50 | recognizer.direction = UISwipeGestureRecognizerDirectionRight; 51 | [self.superview addGestureRecognizer:recognizer]; 52 | 53 | recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(dejal_moveLeftByWord)]; 54 | recognizer.direction = UISwipeGestureRecognizerDirectionLeft; 55 | recognizer.numberOfTouchesRequired = 2; 56 | [self.superview addGestureRecognizer:recognizer]; 57 | 58 | recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(dejal_moveRightByWord)]; 59 | recognizer.direction = UISwipeGestureRecognizerDirectionRight; 60 | recognizer.numberOfTouchesRequired = 2; 61 | [self.superview addGestureRecognizer:recognizer]; 62 | } 63 | 64 | /** 65 | Gesture handler to move the current selection right by one letter. 66 | 67 | @author DJS 2013-03, based on code by JH. 68 | */ 69 | 70 | - (void)dejal_moveLeftByLetter; 71 | { 72 | NSRange selection = self.dejal_selectedRange; 73 | NSUInteger end = selection.location + selection.length; 74 | 75 | if (!selection.length && end > 0) 76 | { 77 | end--; 78 | selection.location = end; 79 | } 80 | 81 | selection.length = 0; 82 | self.dejal_selectedRange = selection; 83 | } 84 | 85 | /** 86 | Gesture handler to move the current selection right by one letter. 87 | 88 | @author DJS 2013-03, based on code by JH. 89 | */ 90 | 91 | - (void)dejal_moveRightByLetter; 92 | { 93 | NSRange selection = self.dejal_selectedRange; 94 | NSUInteger end = selection.location + selection.length; 95 | 96 | if (!selection.length && end < self.text.length) 97 | end++; 98 | 99 | selection.location = end; 100 | selection.length = 0; 101 | self.dejal_selectedRange = selection; 102 | } 103 | 104 | /** 105 | Gesture handler to move the current selection left by one word. 106 | 107 | @author DJS 2013-03, based on code by JH. 108 | */ 109 | 110 | - (void)dejal_moveLeftByWord; 111 | { 112 | NSRange selection = self.dejal_selectedRange; 113 | NSUInteger end = selection.location + selection.length; 114 | 115 | if (selection.length) 116 | { 117 | selection.length = 0; 118 | self.dejal_selectedRange = selection; 119 | return; 120 | } 121 | 122 | NSArray *words = [self.text componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; 123 | NSScanner *scanner = [NSScanner scannerWithString:self.text]; 124 | NSUInteger begin = 0; 125 | 126 | [scanner setScanLocation:0]; 127 | 128 | for (NSString *word in words) 129 | { 130 | if ([scanner scanUpToString:word intoString:nil]) 131 | { 132 | NSUInteger scanLocation = [scanner scanLocation]; 133 | 134 | if (scanLocation < end) 135 | begin = scanLocation; 136 | } 137 | } 138 | 139 | selection.location = begin; 140 | selection.length = 0; 141 | self.dejal_selectedRange = selection; 142 | } 143 | 144 | /** 145 | Gesture handler to move the current selection right by one word. 146 | 147 | @author DJS 2013-03, based on code by JH. 148 | */ 149 | 150 | - (void)dejal_moveRightByWord; 151 | { 152 | NSRange selection = self.dejal_selectedRange; 153 | NSUInteger end = selection.location + selection.length; 154 | 155 | if (selection.length) 156 | { 157 | selection.location = end; 158 | selection.length = 0; 159 | self.dejal_selectedRange = selection; 160 | return; 161 | } 162 | 163 | NSArray *words = [self.text componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; 164 | NSScanner *scanner = [NSScanner scannerWithString:self.text]; 165 | NSUInteger location = self.text.length; 166 | 167 | [scanner setScanLocation:0]; 168 | 169 | for (NSString *word in words) 170 | { 171 | if ([scanner scanUpToString:word intoString:nil]) 172 | { 173 | NSUInteger scanLocation = [scanner scanLocation]; 174 | 175 | if (scanLocation > end) 176 | { 177 | location = scanLocation; 178 | break; 179 | } 180 | } 181 | } 182 | 183 | selection.location = location; 184 | selection.length = 0; 185 | self.dejal_selectedRange = selection; 186 | } 187 | 188 | /** 189 | Returns the current selection range of the receiver. 190 | 191 | @author DJS 2013-03, based on code by JH. 192 | */ 193 | 194 | - (NSRange)dejal_selectedRange; 195 | { 196 | UITextRange *selectedRange = self.selectedTextRange; 197 | NSInteger location = [self offsetFromPosition:self.beginningOfDocument toPosition:selectedRange.start]; 198 | NSInteger length = [self offsetFromPosition:selectedRange.start toPosition:selectedRange.end]; 199 | 200 | return NSMakeRange(location, length); 201 | } 202 | 203 | /** 204 | Sets the selection range of the receiver. 205 | 206 | @author DJS 2013-03, based on code by JH. 207 | */ 208 | 209 | - (void)dejal_setSelectedRange:(NSRange)range; 210 | { 211 | UITextPosition *beginning = self.beginningOfDocument; 212 | UITextPosition *start = [self positionFromPosition:beginning offset:range.location]; 213 | UITextPosition *end = [self positionFromPosition:beginning offset:range.location + range.length]; 214 | UITextRange *selectionRange = [self textRangeFromPosition:start toPosition:end]; 215 | 216 | [self setSelectedTextRange:selectionRange]; 217 | } 218 | 219 | @end 220 | 221 | -------------------------------------------------------------------------------- /UIView+Dejal.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Dejal.m 3 | // Dejal Open Source Categories 4 | // 5 | // Created by David Sinclair on 2009-02-04. 6 | // Copyright (c) 2009-2015 Dejal Systems, LLC. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // - Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // 14 | // - Redistributions in binary form must reproduce the above copyright notice, 15 | // this list of conditions and the following disclaimer in the documentation 16 | // and/or other materials provided with the distribution. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | 30 | #import "UIView+Dejal.h" 31 | @import QuartzCore; 32 | 33 | 34 | @implementation UIView (Dejal) 35 | 36 | /** 37 | Returns the receiver’s frame origin. 38 | 39 | @author DJS 2009-11. 40 | */ 41 | 42 | - (CGPoint)dejal_frameOrigin; 43 | { 44 | return self.frame.origin; 45 | } 46 | 47 | /** 48 | Sets the receiver's frame origin, without tedious local variables or hassles. 49 | 50 | @author DJS 2009-11. 51 | */ 52 | 53 | - (void)dejal_setFrameOrigin:(CGPoint)origin; 54 | { 55 | self.frame = CGRectMake(origin.x, origin.y, self.frame.size.width, self.frame.size.height); 56 | } 57 | 58 | /** 59 | Returns the receiver's frame origin X position. 60 | 61 | @author DJS 2009-11. 62 | */ 63 | 64 | - (CGFloat)dejal_frameX; 65 | { 66 | return self.frame.origin.x; 67 | } 68 | 69 | /** 70 | Sets the receiver's frame origin X position, without tedious local variables or hassles. 71 | 72 | @author DJS 2009-11. 73 | */ 74 | 75 | - (void)dejal_setFrameX:(CGFloat)x; 76 | { 77 | self.dejal_frameOrigin = CGPointMake(x, self.dejal_frameY); 78 | } 79 | 80 | /** 81 | Returns the receiver's frame origin Y position. 82 | 83 | @author DJS 2009-11. 84 | */ 85 | 86 | - (CGFloat)dejal_frameY; 87 | { 88 | return self.frame.origin.y; 89 | } 90 | 91 | /** 92 | Sets the receiver's frame origin Y position, without tedious local variables or hassles. 93 | 94 | @author DJS 2009-11. 95 | */ 96 | 97 | - (void)dejal_setFrameY:(CGFloat)y; 98 | { 99 | self.dejal_frameOrigin = CGPointMake(self.dejal_frameX, y); 100 | } 101 | 102 | 103 | // ---------------------------------------------------------------------------------------- 104 | #pragma mark - 105 | // ---------------------------------------------------------------------------------------- 106 | 107 | 108 | /** 109 | Returns the receiver’s bounds size. 110 | 111 | @author DJS 2009-10. 112 | */ 113 | 114 | - (CGSize)dejal_boundsSize; 115 | { 116 | return self.bounds.size; 117 | } 118 | 119 | /** 120 | Sets the receiver's bounds size, without tedious local variables or hassles. 121 | 122 | @author DJS 2009-10. 123 | */ 124 | 125 | - (void)dejal_setBoundsSize:(CGSize)size; 126 | { 127 | self.bounds = CGRectMake(self.bounds.origin.x, self.bounds.origin.y, size.width, size.height); 128 | } 129 | 130 | /** 131 | Returns the receiver's bounds size width. 132 | 133 | @author DJS 2009-10. 134 | */ 135 | 136 | - (CGFloat)dejal_boundsWidth; 137 | { 138 | return self.bounds.size.width; 139 | } 140 | 141 | /** 142 | Sets the receiver's bounds size width, without tedious local variables or hassles. 143 | 144 | @author DJS 2009-10. 145 | */ 146 | 147 | - (void)dejal_setBoundsWidth:(CGFloat)width; 148 | { 149 | self.dejal_boundsSize = CGSizeMake(width, self.dejal_boundsHeight); 150 | } 151 | 152 | /** 153 | Returns the receiver's bounds size height. 154 | 155 | @author DJS 2009-10. 156 | */ 157 | 158 | - (CGFloat)dejal_boundsHeight; 159 | { 160 | return self.bounds.size.height; 161 | } 162 | 163 | /** 164 | Sets the receiver's bounds size height, without tedious local variables or hassles. 165 | 166 | @author DJS 2009-10. 167 | */ 168 | 169 | - (void)dejal_setBoundsHeight:(CGFloat)height; 170 | { 171 | self.dejal_boundsSize = CGSizeMake(self.dejal_boundsWidth, height); 172 | } 173 | 174 | 175 | // ---------------------------------------------------------------------------------------- 176 | #pragma mark - 177 | // ---------------------------------------------------------------------------------------- 178 | 179 | 180 | /** 181 | Returns an image representation of the receiver and its subviews. 182 | 183 | @author DJS 2009-02. 184 | */ 185 | 186 | - (UIImage *)dejal_imageRepresentation; 187 | { 188 | UIGraphicsBeginImageContext(self.frame.size); 189 | [self.layer renderInContext:UIGraphicsGetCurrentContext()]; 190 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 191 | UIGraphicsEndImageContext(); 192 | 193 | return image; 194 | } 195 | 196 | 197 | // ---------------------------------------------------------------------------------------- 198 | #pragma mark - 199 | // ---------------------------------------------------------------------------------------- 200 | 201 | 202 | /** 203 | Shows or hides the reciever by fading it in or out if animated is YES, or just shows or hides immediately. Uses an animation duration of 0.3, which is the same as the keyboard animation. 204 | 205 | @author DJS 2009-10. 206 | */ 207 | 208 | - (void)dejal_setHidden:(BOOL)hide animated:(BOOL)animated; 209 | { 210 | [self dejal_setHidden:hide animated:animated withDuration:0.3]; 211 | } 212 | 213 | /** 214 | Shows or hides the reciever by fading it in or out if animated is YES, or just shows or hides immediately. An animation duration can be specified (ignored if not animating). 215 | 216 | @author DJS 2009-10. 217 | */ 218 | 219 | - (void)dejal_setHidden:(BOOL)hide animated:(BOOL)animated withDuration:(NSTimeInterval)duration; 220 | { 221 | if (!hide) 222 | { 223 | self.alpha = 0.0; 224 | self.hidden = NO; 225 | } 226 | 227 | if (animated) 228 | { 229 | [UIView beginAnimations:@"DejalViewExtrasHiding" context:(__bridge void *)(@(hide))]; 230 | [UIView setAnimationBeginsFromCurrentState:YES]; 231 | [UIView setAnimationDuration:duration]; 232 | [UIView setAnimationDelegate:self]; 233 | [UIView setAnimationDidStopSelector:@selector(hideAnimationDidStop:finished:hiding:)]; 234 | } 235 | 236 | if (!hide) 237 | self.alpha = 1.0; 238 | else if (animated) 239 | self.alpha = 0.0; 240 | else 241 | self.hidden = YES; 242 | 243 | if (animated) 244 | [UIView commitAnimations]; 245 | } 246 | 247 | /** 248 | Hides the receiver once the hide animation has stopped when hiding; does nothing when showing (but is still called, to avoid it getting called mistakenly if the hiding is interrupted by a show). 249 | 250 | @author DJS 2009-10. 251 | */ 252 | 253 | - (void)hideAnimationDidStop:(NSString *)animationID finished:(NSNumber *)finished hiding:(NSNumber *)hide; 254 | { 255 | if ([animationID isEqualToString:@"DejalViewExtrasHiding"] && finished && [hide boolValue] && self.alpha == 0.0) 256 | self.hidden = YES; 257 | } 258 | 259 | 260 | // ---------------------------------------------------------------------------------------- 261 | #pragma mark - 262 | // ---------------------------------------------------------------------------------------- 263 | 264 | 265 | /** 266 | Adds the reciever as a subview of the specified view, optionally fading it in with animation. Uses an animation duration of 0.3, which is the same as the keyboard animation. 267 | 268 | @author DJS 2009-10. 269 | */ 270 | 271 | - (void)dejal_addToSuperview:(UIView *)view animated:(BOOL)animated; 272 | { 273 | [self dejal_addToSuperview:view animated:animated withDuration:0.3]; 274 | } 275 | 276 | /** 277 | Adds the reciever as a subview of the specified view, optionally fading it in with animation. An animation duration can be specified (ignored if not animating). 278 | 279 | @author DJS 2009-10. 280 | */ 281 | 282 | - (void)dejal_addToSuperview:(UIView *)view animated:(BOOL)animated withDuration:(NSTimeInterval)duration; 283 | { 284 | if (animated) 285 | self.alpha = 0.0; 286 | 287 | if (!self.superview) 288 | [view addSubview:self]; 289 | 290 | if (animated) 291 | { 292 | [UIView beginAnimations:@"DejalViewExtrasAddToSuperview" context:NULL]; 293 | [UIView setAnimationBeginsFromCurrentState:YES]; 294 | [UIView setAnimationDuration:duration]; 295 | 296 | self.alpha = 1.0; 297 | 298 | [UIView commitAnimations]; 299 | } 300 | } 301 | 302 | /** 303 | Removes the reciever from its superview, optionally fading it out with animation. Uses an animation duration of 0.3, which is the same as the keyboard animation. 304 | 305 | @author DJS 2009-10. 306 | */ 307 | 308 | - (void)dejal_removeFromSuperviewAnimated:(BOOL)animated; 309 | { 310 | [self dejal_removeFromSuperviewAnimated:animated withDuration:0.3]; 311 | } 312 | 313 | /** 314 | Removes the reciever from its superview, optionally fading it out with animation. An animation duration can be specified (ignored if not animating). 315 | 316 | @author DJS 2009-10. 317 | */ 318 | 319 | - (void)dejal_removeFromSuperviewAnimated:(BOOL)animated withDuration:(NSTimeInterval)duration; 320 | { 321 | if (!self.superview) 322 | return; 323 | 324 | if (animated) 325 | { 326 | [UIView beginAnimations:@"DejalViewExtrasRemoveFromSuperview" context:NULL]; 327 | [UIView setAnimationBeginsFromCurrentState:YES]; 328 | [UIView setAnimationDuration:duration]; 329 | [UIView setAnimationDelegate:self]; 330 | [UIView setAnimationDidStopSelector:@selector(dejal_removeFromSuperviewAnimationDidStop:finished:context:)]; 331 | 332 | self.alpha = 0.0; 333 | 334 | [UIView commitAnimations]; 335 | } 336 | else 337 | [self removeFromSuperview]; 338 | } 339 | 340 | /** 341 | Removes the receiver from the superview once the hide animation has stopped. 342 | 343 | @author DJS 2009-10. 344 | */ 345 | 346 | - (void)dejal_removeFromSuperviewAnimationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context; 347 | { 348 | if ([animationID isEqualToString:@"DejalViewExtrasRemoveFromSuperview"] && finished && self.alpha == 0.0) 349 | [self removeFromSuperview]; 350 | } 351 | 352 | @end 353 | 354 | -------------------------------------------------------------------------------- /UILabel+Dejal.m: -------------------------------------------------------------------------------- 1 | // 2 | // UILabel+Dejal.m 3 | // Dejal Open Source Categories 4 | // 5 | // Created by David Sinclair on 2008-11-15. 6 | // Copyright (c) 2008-2015 Dejal Systems, LLC. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // - Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // 14 | // - Redistributions in binary form must reproduce the above copyright notice, 15 | // this list of conditions and the following disclaimer in the documentation 16 | // and/or other materials provided with the distribution. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | 30 | #import "UILabel+Dejal.h" 31 | #import "UIColor+Dejal.h" 32 | 33 | 34 | @implementation UILabel (Dejal) 35 | 36 | /** 37 | Returns an autoreleased label with the specified text and default formatting, sized to fit the text. 38 | 39 | @author DJS 2008-11. 40 | */ 41 | 42 | + (UILabel *)dejal_labelWithText:(NSString *)text font:(UIFont *)font; 43 | { 44 | return [self dejal_labelWithText:text font:font width:0.0 height:0.0]; 45 | } 46 | 47 | /** 48 | Returns an autoreleased label with the specified text and default formatting. Pass zero for width to use the width of the text (i.e. sized to fit), or another width. Pass zero for the height to use the height of the text, or another height (e.g. to match baselines with other text). 49 | 50 | @author DJS 2008-11. 51 | */ 52 | 53 | + (UILabel *)dejal_labelWithText:(NSString *)text font:(UIFont *)font width:(CGFloat)width height:(CGFloat)height; 54 | { 55 | CGSize size = [text sizeWithAttributes:@{NSFontAttributeName : font}]; 56 | 57 | if (width <= 5.0) 58 | width = ceil(size.width); 59 | 60 | if (height <= 5.0) 61 | height = ceil(size.height); 62 | 63 | CGRect frame = CGRectMake(0.0, 0.0, width, height); 64 | UILabel *label = [[UILabel alloc] initWithFrame:frame]; 65 | 66 | label.text = text; 67 | label.font = font; 68 | 69 | return label; 70 | } 71 | 72 | /** 73 | Returns an autoreleased label with the specified text and attributes, sized vertically to fit. The text is centered by default. Pass zero for width to default to 320.0, or another width. Pass NSLineBreakModeWordWrap to use multi-line text, or another line break mode as desired. 74 | 75 | @author DJS 2009-11. 76 | @version DJS 2011-12: changed to ensure a minimum of one line, and split the method into two parts. 77 | @version DJS 2012-01: changed to call the following method instead of the previous one. 78 | */ 79 | 80 | + (UILabel *)dejal_labelWithText:(NSString *)text font:(UIFont *)font width:(CGFloat)width lineBreakMode:(NSLineBreakMode)lineBreakMode; 81 | { 82 | CGSize size = CGSizeMake(width, 1000.0); 83 | BOOL isEmpty = !text; 84 | 85 | if (isEmpty) 86 | text = @"\n"; 87 | 88 | size = [self dejal_sizeForText:text font:font lineBreakMode:lineBreakMode frameSize:size]; 89 | 90 | if (isEmpty) 91 | text = nil; 92 | 93 | return [self dejal_labelWithText:text font:font width:width height:size.height lineBreakMode:lineBreakMode]; 94 | } 95 | 96 | /** 97 | Returns an autoreleased label with the specified text and attributes. The text is centered by default. Pass zero for width to default to 320.0, or another width. Pass NSLineBreakModeWordWrap to use multi-line text, or another line break mode as desired. 98 | 99 | @author DJS 2009-11. 100 | @version DJS 2011-12: changed to ensure a minimum of one line, and split the method into two parts. 101 | */ 102 | 103 | + (UILabel *)dejal_labelWithText:(NSString *)text font:(UIFont *)font width:(CGFloat)width height:(CGFloat)height lineBreakMode:(NSLineBreakMode)lineBreakMode; 104 | { 105 | if (width <= 5.0) 106 | width = 320.0; 107 | 108 | if (height <= 5.0) 109 | height = 20.0; 110 | 111 | CGRect frame = CGRectMake(0.0, 0.0, width, height); 112 | UILabel *label = [[UILabel alloc] initWithFrame:frame]; 113 | 114 | label.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin); 115 | label.text = text; 116 | label.font = font; 117 | label.lineBreakMode = lineBreakMode; 118 | label.numberOfLines = 0; 119 | label.textAlignment = NSTextAlignmentCenter; 120 | 121 | return label; 122 | } 123 | 124 | /** 125 | Returns an autoreleased label with the specified text and formatted for use to the left of a text field or table row. 126 | 127 | @author DJS 2008-11. 128 | */ 129 | 130 | + (UILabel *)dejal_labelForPrompt:(NSString *)text withWidth:(CGFloat)width; 131 | { 132 | UIFont *font = [UIFont boldSystemFontOfSize:12]; 133 | UILabel *label = [self dejal_labelWithText:text font:font width:width height:0.0]; 134 | 135 | label.textColor = [UIColor dejal_promptTextColor]; 136 | label.textAlignment = NSTextAlignmentRight; 137 | label.backgroundColor = [UIColor clearColor]; 138 | 139 | return label; 140 | } 141 | 142 | /** 143 | Returns an autoreleased label optimized for table cells, with the specified font, no frame, and a white opaque background. 144 | 145 | @author DJS 2008-11. 146 | */ 147 | 148 | + (UILabel *)dejal_labelForTableCellWithFont:(UIFont *)font textColor:(UIColor *)textColor highlightedTextColor:(UIColor *)highlightedTextColor; 149 | { 150 | UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero]; 151 | 152 | label.font = font; 153 | label.textColor = textColor; 154 | label.highlightedTextColor = highlightedTextColor; 155 | label.backgroundColor = [UIColor whiteColor]; 156 | 157 | return label; 158 | } 159 | 160 | /** 161 | Returns an autoreleased label formatted for use in an add table cell. 162 | 163 | @author DJS 2008-11. 164 | @version DJS 2009-02: changed to use -labelForTableCellWithFont:. 165 | */ 166 | 167 | + (UILabel *)dejal_labelForTableAddRow; 168 | { 169 | return [self dejal_labelForTableCellWithFont:[UIFont boldSystemFontOfSize:16] textColor:[UIColor darkGrayColor] highlightedTextColor:[UIColor lightGrayColor]]; 170 | } 171 | 172 | /** 173 | Returns an autoreleased label formatted for use as the primary value of a table cell. 174 | 175 | @author DJS 2008-11. 176 | @version DJS 2009-02: changed to use -labelForTableCellWithFont:. 177 | */ 178 | 179 | + (UILabel *)dejal_labelForTablePrimaryText; 180 | { 181 | return [self dejal_labelForTableCellWithFont:[UIFont boldSystemFontOfSize:18] textColor:[UIColor blackColor] highlightedTextColor:[UIColor whiteColor]]; 182 | } 183 | 184 | /** 185 | Returns an autoreleased label formatted for use as a secondary value of a table cell. 186 | 187 | @author DJS 2009-02. 188 | */ 189 | 190 | + (UILabel *)dejal_labelForTableSecondaryText; 191 | { 192 | return [self dejal_labelForTableCellWithFont:[UIFont systemFontOfSize:12] textColor:[UIColor darkGrayColor] highlightedTextColor:[UIColor lightGrayColor]]; 193 | } 194 | 195 | /** 196 | Adjusts the receiver when it is highlighted or dehighlighted, so it is opaque with a white background and normal text color when not highlighted (for optimal drawing in tables), and clear background and highlighted text color when highlighted. 197 | 198 | @author DJS 2009-02. 199 | */ 200 | 201 | - (void)dejal_adjustForHighlight:(BOOL)highlighted; 202 | { 203 | NSLog(@"adjustForHighlight: I don't think this is needed anymore; set textColor and highlightedTextColor instead"); // log 204 | 205 | return; 206 | 207 | 208 | UIColor *backgroundColor = highlighted ? [UIColor clearColor] : [UIColor whiteColor]; 209 | 210 | self.backgroundColor = backgroundColor; 211 | self.highlighted = highlighted; 212 | 213 | [self setNeedsDisplay]; 214 | } 215 | 216 | /** 217 | Returns the size of the text within the frame size. 218 | 219 | @param text The text for the label. 220 | @param font The font to use for the text. 221 | @param lineBreakMode The line break mode. 222 | @param frameSize The size of the frame that contains the receiver. 223 | @returns The size that the text takes up. 224 | 225 | @author DJS 2014-01. 226 | */ 227 | 228 | + (CGSize)dejal_sizeForText:(NSString *)text font:(UIFont *)font lineBreakMode:(NSLineBreakMode)lineBreakMode frameSize:(CGSize)frameSize; 229 | { 230 | NSMutableParagraphStyle *paragraph = [NSMutableParagraphStyle new]; 231 | paragraph.lineBreakMode = lineBreakMode; 232 | 233 | CGSize textSize = [text boundingRectWithSize:frameSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : font, NSParagraphStyleAttributeName : paragraph} context:nil].size; 234 | 235 | return textSize; 236 | } 237 | 238 | /** 239 | Returns the size of the attributed text within the frame size. 240 | 241 | @param text The attributed text for the label. 242 | @param frameSize The size of the frame that contains the receiver. 243 | @returns The size that the text takes up. 244 | 245 | @author DJS 2014-11. 246 | */ 247 | 248 | + (CGSize)dejal_sizeForAttributedText:(NSAttributedString *)text frameSize:(CGSize)frameSize; 249 | { 250 | CGSize textSize = [text boundingRectWithSize:frameSize options:NSStringDrawingUsesLineFragmentOrigin context:nil].size; 251 | 252 | return textSize; 253 | } 254 | 255 | /** 256 | Returns the size of the text within the frame size. 257 | 258 | @param frameSize The size of the frame that contains the receiver. 259 | @returns The size that the text takes up. 260 | 261 | @author DJS 2014-01. 262 | */ 263 | 264 | - (CGSize)dejal_sizeForTextWithinFrameSize:(CGSize)frameSize; 265 | { 266 | return [[self class] dejal_sizeForText:self.text font:self.font lineBreakMode:self.lineBreakMode frameSize:frameSize]; 267 | } 268 | 269 | /** 270 | Returns the size of the attributed text within the frame size. 271 | 272 | @param frameSize The size of the frame that contains the receiver. 273 | @returns The size that the text takes up. 274 | 275 | @author DJS 2014-11. 276 | */ 277 | 278 | - (CGSize)dejal_sizeForAttributedTextWithinFrameSize:(CGSize)frameSize; 279 | { 280 | return [[self class] dejal_sizeForAttributedText:self.attributedText frameSize:frameSize]; 281 | } 282 | 283 | @end 284 | 285 | -------------------------------------------------------------------------------- /UIImage+Dejal.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Dejal.m 3 | // Dejal Open Source Categories 4 | // 5 | // Created by David Sinclair on 2009-09-29. 6 | // Copyright (c) 2009-2015 Dejal Systems, LLC. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // - Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // 14 | // - Redistributions in binary form must reproduce the above copyright notice, 15 | // this list of conditions and the following disclaimer in the documentation 16 | // and/or other materials provided with the distribution. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | 30 | #import "UIImage+Dejal.h" 31 | 32 | 33 | @implementation UIImage (Dejal) 34 | 35 | /** 36 | Returns the named image, recolored white, either from a cache, or added to the cache. Useful for highlighted table cell icons. 37 | 38 | @author DJS 2012-06. 39 | @version DJS 2013-01: changed to use +imageNamed:withOverlayColor:. 40 | @version DJS 2013-11: changed to return an unrecolored image on iOS 7 and later; remove uses of this method once that is the minimum. 41 | */ 42 | 43 | + (UIImage *)dejal_whiteTintedImageNamed:(NSString *)name; 44 | { 45 | if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) 46 | return [self dejal_imageNamed:name withOverlayColor:[UIColor whiteColor]]; 47 | else 48 | return [self imageNamed:name]; 49 | } 50 | 51 | /** 52 | Returns the named image, recolored gray, either from a cache, or added to the cache. Useful for disabled table cell icons. 53 | 54 | @author DJS 2013-01. 55 | */ 56 | 57 | + (UIImage *)dejal_grayTintedImageNamed:(NSString *)name; 58 | { 59 | return [self dejal_imageNamed:name withOverlayColor:[UIColor grayColor]]; 60 | } 61 | 62 | /** 63 | Given an array of images, returns them all with a white overlay. 64 | 65 | @author DJS 2012-06. 66 | */ 67 | 68 | + (NSArray *)dejal_whiteTintedImages:(NSArray *)imageArray; 69 | { 70 | NSMutableArray *tintedArray = [NSMutableArray arrayWithCapacity:imageArray.count]; 71 | 72 | for (UIImage *image in imageArray) 73 | [tintedArray addObject:[image dejal_imageWithWhiteOverlay]]; 74 | 75 | return tintedArray; 76 | } 77 | 78 | /** 79 | Returns a new autoreleased copy of the receiever, recolored white. Useful for highlighted table cell icons. Better to use +whiteTintedImageNamed:, though, so it is cached. 80 | 81 | @author DJS 2011-10. 82 | @version DJS 2013-11: changed to return the receiver on iOS 7 and later; remove uses of this method once that is the minimum. 83 | */ 84 | 85 | - (UIImage *)dejal_imageWithWhiteOverlay; 86 | { 87 | if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) 88 | return [self dejal_imageWithOverlayColor:[UIColor whiteColor]]; 89 | else 90 | return self; 91 | } 92 | 93 | /** 94 | Returns a new autoreleased copy of the receiever, recolored gray. Useful for disabled table cell icons. Better to use +grayTintedImageNamed:, though, so it is cached. 95 | 96 | @author DJS 2012-10. 97 | */ 98 | 99 | - (UIImage *)dejal_imageWithGrayOverlay; 100 | { 101 | return [self dejal_imageWithOverlayColor:[UIColor grayColor]]; 102 | } 103 | 104 | /** 105 | Given the name of an image and an overlay color, returns that image with that overlay, either from a cache, or added to the cache. If the overlay color is nil, does the same as +imageNamed:. 106 | 107 | @author DJS 2013-01. 108 | */ 109 | 110 | + (UIImage *)dejal_imageNamed:(NSString *)name withOverlayColor:(UIColor *)color; 111 | { 112 | if (!color) 113 | return [self imageNamed:name]; 114 | 115 | static NSMutableDictionary *dejalImageCache = nil; 116 | 117 | if (!dejalImageCache) 118 | dejalImageCache = [NSMutableDictionary dictionary]; 119 | 120 | NSString *key = [NSString stringWithFormat:@"%@ %@", name, [color description]]; 121 | UIImage *image = dejalImageCache[key]; 122 | 123 | if (!image) 124 | { 125 | image = [[self imageNamed:name] dejal_imageWithOverlayColor:color]; 126 | dejalImageCache[key] = image; 127 | } 128 | 129 | return image; 130 | } 131 | 132 | /** 133 | Returns a new autoreleased copy of the receiver, recolored as requested. 134 | 135 | @author DJS 2011-10: based on http://stackoverflow.com/questions/1223340/iphone-how-do-you-color-an-image 136 | @version DJS 2012-06: changed to remove pre-iOS 4 stuff. 137 | */ 138 | 139 | - (UIImage *)dejal_imageWithOverlayColor:(UIColor *)color; 140 | { 141 | CGRect rect = CGRectMake(0.0f, 0.0f, self.size.width, self.size.height); 142 | 143 | UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale); 144 | 145 | [self drawInRect:rect]; 146 | 147 | CGContextRef context = UIGraphicsGetCurrentContext(); 148 | CGContextSetBlendMode(context, kCGBlendModeSourceIn); 149 | 150 | CGContextSetFillColorWithColor(context, color.CGColor); 151 | CGContextFillRect(context, rect); 152 | 153 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 154 | 155 | UIGraphicsEndImageContext(); 156 | 157 | return image; 158 | } 159 | 160 | /** 161 | Returns a new autoreleased copy of the receiver, scaled and cropped to the specified size, keeping the aspect ratio, or returns the receiver if it is already the specified size. If canScaleUp is NO, it is not scaled if smaller than the specified size. Note: this method is not thread-safe. 162 | 163 | @author DJS 2009-10. 164 | */ 165 | 166 | - (UIImage *)dejal_imageAspectScaledToSize:(CGSize)newSize canScaleUp:(BOOL)canScaleUp; 167 | { 168 | return [self dejal_imageAspectScaledToSize:newSize canScaleUp:canScaleUp threadSafe:NO]; 169 | } 170 | 171 | /** 172 | Returns a new autoreleased copy of the receiver, scaled and cropped to the specified size, keeping the aspect ratio, or returns the receiver if it is already the specified size. If canScaleUp is NO, it is not scaled if smaller than the specified size. Pass YES for threadSafe to do it in a thread-safe way, though it currently doesn't support all downloaded images (gives an error like ": CGBitmapContextCreate: unsupported parameter combination: 8 integer bits/component; 32 bits/pixel; 3-component colorspace; kCGImageAlphaLast; 512 bytes/row"). 173 | 174 | @author DJS 2009-10: based on http://stackoverflow.com/questions/1282830/uiimagepickercontroller-uiimage-memory-and-more 175 | */ 176 | 177 | - (UIImage *)dejal_imageAspectScaledToSize:(CGSize)newSize canScaleUp:(BOOL)canScaleUp threadSafe:(BOOL)threadSafe; 178 | { 179 | CGSize imageSize = self.size; 180 | 181 | // Return the receiver if it is already the right size: 182 | if (CGSizeEqualToSize(imageSize, newSize)) 183 | return self; 184 | 185 | if (!canScaleUp && imageSize.width <= newSize.width && imageSize.height <= newSize.height) 186 | return self; 187 | 188 | UIImage *newImage = nil; 189 | CGFloat width = imageSize.width; 190 | CGFloat height = imageSize.height; 191 | CGFloat newWidth = newSize.width; 192 | CGFloat newHeight = newSize.height; 193 | CGFloat scaleFactor = 0.0; 194 | CGFloat scaledWidth = 0.0; 195 | CGFloat scaledHeight = 0.0; 196 | CGPoint thumbnailPoint = CGPointMake(0.0, 0.0); 197 | CGFloat widthFactor = newWidth / width; 198 | CGFloat heightFactor = newHeight / height; 199 | 200 | // Scale to fit height or width: 201 | if (widthFactor > heightFactor) 202 | scaleFactor = widthFactor; 203 | else 204 | scaleFactor = heightFactor; 205 | 206 | scaledWidth = width * scaleFactor; 207 | scaledHeight = height * scaleFactor; 208 | 209 | // Center the image: 210 | if (widthFactor > heightFactor) 211 | thumbnailPoint.y = (newHeight - scaledHeight) * 0.5; 212 | else if (widthFactor < heightFactor) 213 | thumbnailPoint.x = (newWidth - scaledWidth) * 0.5; 214 | 215 | if (threadSafe) 216 | { 217 | CGImageRef imageRef = [self CGImage]; 218 | CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef); 219 | CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef); 220 | 221 | if (bitmapInfo == kCGImageAlphaNone) 222 | bitmapInfo = kCGImageAlphaNoneSkipLast; 223 | 224 | CGContextRef bitmap; 225 | 226 | if (self.imageOrientation == UIImageOrientationUp || self.imageOrientation == UIImageOrientationDown) 227 | bitmap = CGBitmapContextCreate(NULL, newWidth, newHeight, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo); 228 | else 229 | bitmap = CGBitmapContextCreate(NULL, newHeight, newWidth, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo); 230 | 231 | // In the right or left cases, we need to switch scaledWidth and scaledHeight, and also the thumbnail point: 232 | if (self.imageOrientation == UIImageOrientationLeft) 233 | { 234 | thumbnailPoint = CGPointMake(thumbnailPoint.y, thumbnailPoint.x); 235 | CGFloat oldScaledWidth = scaledWidth; 236 | scaledWidth = scaledHeight; 237 | scaledHeight = oldScaledWidth; 238 | 239 | CGContextRotateCTM(bitmap, DejalDegreesToRadians(90.0)); 240 | CGContextTranslateCTM(bitmap, 0.0, -newHeight); 241 | 242 | } 243 | else if (self.imageOrientation == UIImageOrientationRight) 244 | { 245 | thumbnailPoint = CGPointMake(thumbnailPoint.y, thumbnailPoint.x); 246 | CGFloat oldScaledWidth = scaledWidth; 247 | scaledWidth = scaledHeight; 248 | scaledHeight = oldScaledWidth; 249 | 250 | CGContextRotateCTM(bitmap, DejalDegreesToRadians(-90.0)); 251 | CGContextTranslateCTM(bitmap, -newWidth, 0.0); 252 | 253 | } 254 | else if (self.imageOrientation == UIImageOrientationDown) 255 | { 256 | CGContextTranslateCTM(bitmap, newWidth, newHeight); 257 | CGContextRotateCTM(bitmap, DejalDegreesToRadians(-180.0)); 258 | } 259 | 260 | CGContextDrawImage(bitmap, CGRectMake(thumbnailPoint.x, thumbnailPoint.y, scaledWidth, scaledHeight), imageRef); 261 | CGImageRef ref = CGBitmapContextCreateImage(bitmap); 262 | 263 | newImage = [UIImage imageWithCGImage:ref]; 264 | 265 | CGContextRelease(bitmap); 266 | CGImageRelease(ref); 267 | } 268 | else 269 | { 270 | UIGraphicsBeginImageContext(newSize); 271 | 272 | CGRect thumbnailRect = CGRectZero; 273 | thumbnailRect.origin = thumbnailPoint; 274 | thumbnailRect.size.width = scaledWidth; 275 | thumbnailRect.size.height = scaledHeight; 276 | 277 | [self drawInRect:thumbnailRect]; 278 | 279 | newImage = UIGraphicsGetImageFromCurrentImageContext(); 280 | 281 | if (!newImage) 282 | NSLog(@"could not scale image"); 283 | 284 | UIGraphicsEndImageContext(); 285 | } 286 | 287 | return newImage; 288 | } 289 | 290 | /** 291 | Returns the receiver with the corners rounded off to the specified radius. 292 | 293 | @author DJS 2010-01, with forum help: https://devforums.apple.com/message/156207 294 | */ 295 | 296 | - (UIImage *)dejal_imageMaskedWithCornerRadius:(CGFloat)radius; 297 | { 298 | UIGraphicsBeginImageContext(self.size); 299 | CGContextRef context = UIGraphicsGetCurrentContext(); 300 | 301 | CGFloat midX = self.size.width / 2.0; 302 | CGFloat maxX = self.size.width; 303 | CGFloat midY = self.size.height / 2.0; 304 | CGFloat maxY = self.size.height; 305 | 306 | CGContextMoveToPoint(context, 0.0, midY); 307 | CGContextAddArcToPoint(context, 0.0, 0.0, midX, 0.0, radius); 308 | CGContextAddArcToPoint(context, maxX, 0.0, maxX, midY, radius); 309 | CGContextAddArcToPoint(context, maxX, maxY, midX, maxY, radius); 310 | CGContextAddArcToPoint(context, 0.0, maxY, 0.0, midY, radius); 311 | CGContextClosePath(context); 312 | 313 | CGContextClip(context); 314 | CGContextTranslateCTM(context, 0.0, self.size.height); 315 | CGContextScaleCTM(context, 1.0, -1.0); 316 | 317 | CGContextDrawImage(context, CGRectMake(0.0, 0.0, self.size.width, self.size.height), self.CGImage); 318 | 319 | UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 320 | 321 | UIGraphicsEndImageContext(); 322 | 323 | return newImage; 324 | } 325 | 326 | @end 327 | 328 | --------------------------------------------------------------------------------