Fixed #47. Fixed #48 (Automatic support for right-to-left languages)

This commit is contained in:
Xavier Schott 2018-06-04 17:57:49 -07:00
parent 3603e112c4
commit 1c634aac0f
13 changed files with 204 additions and 50 deletions

View File

@ -2,7 +2,7 @@ Pod::Spec.new do |spec|
# ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
spec.name = "TGPControls" spec.name = "TGPControls"
spec.version = "5.0.1" spec.version = "5.0.3"
spec.summary = "Custom animated iOS controls: Animated discrete slider, animated labels" spec.summary = "Custom animated iOS controls: Animated discrete slider, animated labels"
spec.description = <<-DESC spec.description = <<-DESC
@ -23,9 +23,10 @@ Pod::Spec.new do |spec|
spec.platform = :ios spec.platform = :ios
spec.ios.deployment_target = '8.0' spec.ios.deployment_target = '8.0'
spec.requires_arc = true spec.requires_arc = true
spec.swift_version = '4.0'
# ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
spec.source = { :git => "https://github.com/SwiftArchitect/TGPControls.git", :tag => "v5.0.1" } spec.source = { :git => "https://github.com/SwiftArchitect/TGPControls.git", :tag => "v5.0.3" }
spec.source_files = "TGPControls/**/*.{swift}" spec.source_files = "TGPControls/**/*.{swift}"
spec.exclude_files = "TGPControlsDemo/*" spec.exclude_files = "TGPControlsDemo/*"

View File

@ -78,11 +78,11 @@ public class TGPCamelLabels: TGPCamelLabels_INTERFACE_BUILDER {
} }
} }
@IBInspectable public var numberOfLinesInLabel:Int = 1 { @IBInspectable public var numberOfLinesInLabel:Int = 1 {
didSet { didSet {
layoutTrack() layoutTrack()
} }
} }
// Label off-center to the left and right of the slider // Label off-center to the left and right of the slider
// expressed in label width. 0: none, -1/2: half outside, 1/2; half inside // expressed in label width. 0: none, -1/2: half outside, 1/2; half inside
@ -166,6 +166,7 @@ public class TGPCamelLabels: TGPCamelLabels_INTERFACE_BUILDER {
var lastValue = NSNotFound var lastValue = NSNotFound
var emphasizedLabels:[UILabel] = [] var emphasizedLabels:[UILabel] = []
var regularLabels:[UILabel] = [] var regularLabels:[UILabel] = []
var localeCharacterDirection = CFLocaleLanguageDirection.leftToRight
// MARK: UIView // MARK: UIView
@ -195,6 +196,11 @@ public class TGPCamelLabels: TGPCamelLabels_INTERFACE_BUILDER {
// MARK: TGPCamelLabels // MARK: TGPCamelLabels
func initProperties() { func initProperties() {
if let systemLocale = CFLocaleCopyCurrent(),
let localeIdentifier = CFLocaleGetIdentifier(systemLocale) {
localeCharacterDirection = CFLocaleGetLanguageCharacterDirection(localeIdentifier.rawValue)
}
debugNames(count: 10) debugNames(count: 10)
layoutTrack() layoutTrack()
} }
@ -234,10 +240,16 @@ public class TGPCamelLabels: TGPCamelLabels_INTERFACE_BUILDER {
let count = names.count let count = names.count
if count > 0 { if count > 0 {
var centerX = (bounds.width - (CGFloat(count - 1) * ticksDistance))/2.0 var centerX = (bounds.width - (CGFloat(count - 1) * ticksDistance))/2.0
if .rightToLeft == localeCharacterDirection {
centerX = bounds.width - centerX
}
let tickSpacing = (.rightToLeft == localeCharacterDirection)
? -ticksDistance
: ticksDistance
let centerY = bounds.height / 2.0 let centerY = bounds.height / 2.0
for name in names { for name in names {
let upLabel = UILabel.init() let upLabel = UILabel.init()
upLabel.numberOfLines = self.numberOfLinesInLabel upLabel.numberOfLines = numberOfLinesInLabel
emphasizedLabels.append(upLabel) emphasizedLabels.append(upLabel)
upLabel.text = name upLabel.text = name
if let upFontName = upFontName { if let upFontName = upFontName {
@ -261,7 +273,7 @@ public class TGPCamelLabels: TGPCamelLabels_INTERFACE_BUILDER {
addSubview(upLabel) addSubview(upLabel)
let dnLabel = UILabel.init() let dnLabel = UILabel.init()
dnLabel.numberOfLines = self.numberOfLinesInLabel dnLabel.numberOfLines = numberOfLinesInLabel
regularLabels.append(dnLabel) regularLabels.append(dnLabel)
dnLabel.text = name dnLabel.text = name
if let downFontName = downFontName { if let downFontName = downFontName {
@ -279,15 +291,21 @@ public class TGPCamelLabels: TGPCamelLabels_INTERFACE_BUILDER {
}() }()
addSubview(dnLabel) addSubview(dnLabel)
centerX += ticksDistance centerX += tickSpacing
} }
// Fix left and right label, if there are at least 2 labels // Fix left and right label, if there are at least 2 labels
if names.count > 1 { if names.count > 1 {
insetLabel(emphasizedLabels.first, withInset: insets, andMultiplier: offCenter) let localeInsets = (.rightToLeft == localeCharacterDirection)
insetLabel(emphasizedLabels.last, withInset: -insets, andMultiplier: -offCenter) ? -insets
insetLabel(regularLabels.first, withInset: insets, andMultiplier: offCenter) : insets
insetLabel(regularLabels.last, withInset: -insets, andMultiplier: -offCenter) let localeOffCenter = (.rightToLeft == localeCharacterDirection)
? -offCenter
: offCenter
insetLabel(emphasizedLabels.first, withInset: localeInsets, andMultiplier: localeOffCenter)
insetLabel(emphasizedLabels.last, withInset: -localeInsets, andMultiplier: -localeOffCenter)
insetLabel(regularLabels.first, withInset: localeInsets, andMultiplier: localeOffCenter)
insetLabel(regularLabels.last, withInset: -localeInsets, andMultiplier: -localeOffCenter)
} }
dockEffect(duration:0.0) dockEffect(duration:0.0)

View File

@ -221,15 +221,18 @@ public class TGPDiscreteSlider:TGPSlider_INTERFACE_BUILDER {
var intValue:Int = 0 var intValue:Int = 0
var intMinimumValue = -5 var intMinimumValue = -5
var ticksAbscisses:[CGPoint] = [] var ticksAbscissae:[CGPoint] = []
var thumbAbscisse:CGFloat = 0 var thumbAbscissa:CGFloat = 0
var thumbLayer = CALayer() var thumbLayer = CALayer()
var leftTrackLayer = CALayer() var leftTrackLayer = CALayer()
var rightTrackLayer = CALayer() var rightTrackLayer = CALayer()
var trackLayer = CALayer() var trackLayer = CALayer()
var leadingTrackLayer: CALayer!
var trailingTrackLayer: CALayer!
var ticksLayer = CALayer() var ticksLayer = CALayer()
var trackRectangle = CGRect.zero var trackRectangle = CGRect.zero
var touchedInside = false var touchedInside = false
var localeCharacterDirection = CFLocaleLanguageDirection.leftToRight
let iOSThumbShadowRadius:CGFloat = 4 let iOSThumbShadowRadius:CGFloat = 4
let iOSThumbShadowOffset = CGSize(width:0, height:3) let iOSThumbShadowOffset = CGSize(width:0, height:3)
@ -262,17 +265,30 @@ public class TGPDiscreteSlider:TGPSlider_INTERFACE_BUILDER {
// MARK: TGPDiscreteSlider // MARK: TGPDiscreteSlider
func initProperties() { func initProperties() {
if let systemLocale = CFLocaleCopyCurrent(),
let localeIdentifier = CFLocaleGetIdentifier(systemLocale) {
localeCharacterDirection = CFLocaleGetLanguageCharacterDirection(localeIdentifier.rawValue)
}
leadingTrackLayer = (.rightToLeft == localeCharacterDirection)
? rightTrackLayer
: leftTrackLayer
trailingTrackLayer = (.rightToLeft == localeCharacterDirection)
? leftTrackLayer
: rightTrackLayer
// Track is a clear clipping layer, and left + right sublayers, which brings in free animation // Track is a clear clipping layer, and left + right sublayers, which brings in free animation
trackLayer.masksToBounds = true trackLayer.masksToBounds = true
trackLayer.backgroundColor = UIColor.clear.cgColor trackLayer.backgroundColor = UIColor.clear.cgColor
layer.addSublayer(trackLayer) layer.addSublayer(trackLayer)
if let backgroundColor = tintColor {
leftTrackLayer.backgroundColor = backgroundColor.cgColor
}
trackLayer.addSublayer(leftTrackLayer) trackLayer.addSublayer(leftTrackLayer)
rightTrackLayer.backgroundColor = maximumTrackTintColor.cgColor
trackLayer.addSublayer(rightTrackLayer) trackLayer.addSublayer(rightTrackLayer)
if let backgroundColor = tintColor {
leadingTrackLayer.backgroundColor = backgroundColor.cgColor
}
rightTrackLayer.backgroundColor = maximumTrackTintColor.cgColor
// Ticks in between track and thumb // Ticks in between track and thumb
layer.addSublayer(ticksLayer) layer.addSublayer(ticksLayer)
@ -300,7 +316,7 @@ public class TGPDiscreteSlider:TGPSlider_INTERFACE_BUILDER {
fallthrough fallthrough
case .image: case .image:
for originPoint in ticksAbscisses { for originPoint in ticksAbscissae {
let rectangle = CGRect(x: originPoint.x-(tickSize.width/2), let rectangle = CGRect(x: originPoint.x-(tickSize.width/2),
y: originPoint.y-(tickSize.height/2), y: originPoint.y-(tickSize.height/2),
width: tickSize.width, width: tickSize.width,
@ -391,21 +407,21 @@ public class TGPDiscreteSlider:TGPSlider_INTERFACE_BUILDER {
leftTrackLayer.frame = { leftTrackLayer.frame = {
var frame = trackLayer.bounds var frame = trackLayer.bounds
frame.size.width = thumbAbscisse - trackRectangle.minX frame.size.width = thumbAbscissa - trackRectangle.minX
return frame return frame
}() }()
if let backgroundColor = minimumTrackTintColor ?? tintColor {
leftTrackLayer.backgroundColor = backgroundColor.cgColor
}
rightTrackLayer.frame = { rightTrackLayer.frame = {
var frame = trackLayer.bounds var frame = trackLayer.bounds
frame.size.width = trackRectangle.width - leftTrackLayer.frame.width frame.size.width = trackRectangle.width - leftTrackLayer.frame.width
frame.origin.x = leftTrackLayer.frame.maxX frame.origin.x = leftTrackLayer.frame.maxX
return frame return frame
}() }()
rightTrackLayer.backgroundColor = maximumTrackTintColor.cgColor
if let backgroundColor = minimumTrackTintColor ?? tintColor {
leadingTrackLayer.backgroundColor = backgroundColor.cgColor
}
trailingTrackLayer.backgroundColor = maximumTrackTintColor.cgColor
} }
func drawThumb() { func drawThumb() {
@ -414,7 +430,7 @@ public class TGPDiscreteSlider:TGPSlider_INTERFACE_BUILDER {
let thumbSizeForStyle = thumbSizeIncludingShadow() let thumbSizeForStyle = thumbSizeIncludingShadow()
let thumbWidth = thumbSizeForStyle.width let thumbWidth = thumbSizeForStyle.width
let thumbHeight = thumbSizeForStyle.height let thumbHeight = thumbSizeForStyle.height
let rectangle = CGRect(x:thumbAbscisse - (thumbWidth / 2), let rectangle = CGRect(x:thumbAbscissa - (thumbWidth / 2),
y: (frame.height - thumbHeight)/2, y: (frame.height - thumbHeight)/2,
width: thumbWidth, width: thumbWidth,
height: thumbHeight) height: thumbHeight)
@ -515,11 +531,11 @@ public class TGPDiscreteSlider:TGPSlider_INTERFACE_BUILDER {
width: trackSize.width, width: trackSize.width,
height: trackSize.height) height: trackSize.height)
let trackY = frame.height / 2 let trackY = frame.height / 2
ticksAbscisses = [] ticksAbscissae = []
for iterate in 0 ... segments { for iterate in 0 ... segments {
let ratio = Double(iterate) / Double(segments) let ratio = Double(iterate) / Double(segments)
let originX = trackRectangle.origin.x + (CGFloat)(trackSize.width * CGFloat(ratio)) let originX = trackRectangle.origin.x + (CGFloat)(trackSize.width * CGFloat(ratio))
ticksAbscisses.append(CGPoint(x: originX, y: trackY)) ticksAbscissae.append(CGPoint(x: originX, y: trackY))
} }
layoutThumb() layoutThumb()
@ -536,7 +552,10 @@ public class TGPDiscreteSlider:TGPSlider_INTERFACE_BUILDER {
let nonZeroIncrement = ((0 == incrementValue) ? 1 : incrementValue) let nonZeroIncrement = ((0 == incrementValue) ? 1 : incrementValue)
var thumbRatio = Double(value - minimumValue) / Double(segments * nonZeroIncrement) var thumbRatio = Double(value - minimumValue) / Double(segments * nonZeroIncrement)
thumbRatio = max(0.0, min(thumbRatio, 1.0)) // Normalized thumbRatio = max(0.0, min(thumbRatio, 1.0)) // Normalized
thumbAbscisse = trackRectangle.origin.x + (CGFloat)(trackRectangle.width * CGFloat(thumbRatio)) thumbRatio = (.rightToLeft == localeCharacterDirection)
? 1.0 - thumbRatio
: thumbRatio
thumbAbscissa = trackRectangle.origin.x + (CGFloat)(trackRectangle.width * CGFloat(thumbRatio))
} }
func thumbSizeIncludingShadow() -> CGSize { func thumbSizeIncludingShadow() -> CGSize {
@ -628,14 +647,14 @@ public class TGPDiscreteSlider:TGPSlider_INTERFACE_BUILDER {
func touchDown(_ touches: Set<UITouch>, animationDuration duration:TimeInterval) { func touchDown(_ touches: Set<UITouch>, animationDuration duration:TimeInterval) {
if let touch = touches.first { if let touch = touches.first {
let location = touch.location(in: touch.view) let location = touch.location(in: touch.view)
moveThumbTo(abscisse: location.x, animationDuration: duration) moveThumbTo(abscissa: location.x, animationDuration: duration)
} }
} }
func touchUp(_ touches: Set<UITouch>) { func touchUp(_ touches: Set<UITouch>) {
if let touch = touches.first { if let touch = touches.first {
let location = touch.location(in: touch.view) let location = touch.location(in: touch.view)
let tick = pickTickFromSliderPosition(abscisse: location.x) let tick = pickTickFromSliderPosition(abscissa: location.x)
moveThumbToTick(tick: tick) moveThumbToTick(tick: tick)
} }
} }
@ -665,14 +684,14 @@ public class TGPDiscreteSlider:TGPSlider_INTERFACE_BUILDER {
setNeedsDisplay() setNeedsDisplay()
} }
func moveThumbTo(abscisse:CGFloat, animationDuration duration:TimeInterval) { func moveThumbTo(abscissa:CGFloat, animationDuration duration:TimeInterval) {
let leftMost = trackRectangle.minX let leftMost = trackRectangle.minX
let rightMost = trackRectangle.maxX let rightMost = trackRectangle.maxX
thumbAbscisse = max(leftMost, min(abscisse, rightMost)) thumbAbscissa = max(leftMost, min(abscissa, rightMost))
CATransaction.setAnimationDuration(duration) CATransaction.setAnimationDuration(duration)
let tick = pickTickFromSliderPosition(abscisse: thumbAbscisse) let tick = pickTickFromSliderPosition(abscissa: thumbAbscissa)
let nonZeroIncrement = ((0 == incrementValue) ? 1 : incrementValue) let nonZeroIncrement = ((0 == incrementValue) ? 1 : incrementValue)
let intValue = Int(minimumValue) + (Int(tick) * nonZeroIncrement) let intValue = Int(minimumValue) + (Int(tick) * nonZeroIncrement)
if intValue != self.intValue { if intValue != self.intValue {
@ -683,11 +702,14 @@ public class TGPDiscreteSlider:TGPSlider_INTERFACE_BUILDER {
setNeedsDisplay() setNeedsDisplay()
} }
func pickTickFromSliderPosition(abscisse: CGFloat) -> UInt { func pickTickFromSliderPosition(abscissa: CGFloat) -> UInt {
let leftMost = trackRectangle.minX let leftMost = trackRectangle.minX
let rightMost = trackRectangle.maxX let rightMost = trackRectangle.maxX
let clampedAbscisse = max(leftMost, min(abscisse, rightMost)) let clampedAbscissa = max(leftMost, min(abscissa, rightMost))
let ratio = Double(clampedAbscisse - leftMost) / Double(rightMost - leftMost) var ratio = Double(clampedAbscissa - leftMost) / Double(rightMost - leftMost)
ratio = (.rightToLeft == localeCharacterDirection)
? 1.0 - ratio
: ratio
let segments = max(1, tickCount - 1) let segments = max(1, tickCount - 1)
return UInt(round( Double(segments) * ratio)) return UInt(round( Double(segments) * ratio))
} }

View File

@ -3,8 +3,8 @@ platform :ios, '8.0'
use_frameworks! use_frameworks!
target 'TGPControlsDemo-Pods' do target 'TGPControlsDemo-Pods' do
pod 'TGPControls', :path => '../../TGPControls' #pod 'TGPControls', :path => '../../TGPControls'
#pod 'TGPControls' pod 'TGPControls'
end end

View File

@ -20,6 +20,10 @@
DC56BDCC1E46DEB900AAD0D9 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DC56BDCA1E46DEB900AAD0D9 /* Main.storyboard */; }; DC56BDCC1E46DEB900AAD0D9 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DC56BDCA1E46DEB900AAD0D9 /* Main.storyboard */; };
DC56BDCE1E46DEB900AAD0D9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DC56BDCD1E46DEB900AAD0D9 /* Assets.xcassets */; }; DC56BDCE1E46DEB900AAD0D9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DC56BDCD1E46DEB900AAD0D9 /* Assets.xcassets */; };
DC56BDD11E46DEB900AAD0D9 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DC56BDCF1E46DEB900AAD0D9 /* LaunchScreen.storyboard */; }; DC56BDD11E46DEB900AAD0D9 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DC56BDCF1E46DEB900AAD0D9 /* LaunchScreen.storyboard */; };
DC7677B820C5C5BA006155F3 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = DC7677B620C5C5BA006155F3 /* Localizable.strings */; };
DC7677B920C5C5BA006155F3 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = DC7677B620C5C5BA006155F3 /* Localizable.strings */; };
DC7677BD20C5C712006155F3 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = DC7677BB20C5C712006155F3 /* InfoPlist.strings */; };
DC7677BE20C5C712006155F3 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = DC7677BB20C5C712006155F3 /* InfoPlist.strings */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */ /* Begin PBXCopyFilesBuildPhase section */
@ -50,6 +54,11 @@
DC56BDCD1E46DEB900AAD0D9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; DC56BDCD1E46DEB900AAD0D9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
DC56BDD01E46DEB900AAD0D9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; DC56BDD01E46DEB900AAD0D9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
DC56BDD21E46DEB900AAD0D9 /* TGPControlsDemo-Pods-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "TGPControlsDemo-Pods-Info.plist"; sourceTree = "<group>"; }; DC56BDD21E46DEB900AAD0D9 /* TGPControlsDemo-Pods-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "TGPControlsDemo-Pods-Info.plist"; sourceTree = "<group>"; };
DC7677B720C5C5BA006155F3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Localizable.strings; sourceTree = "<group>"; };
DC7677BA20C5C5E5006155F3 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Localizable.strings; sourceTree = "<group>"; };
DC7677BC20C5C712006155F3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/InfoPlist.strings; sourceTree = "<group>"; };
DC7677BF20C5C769006155F3 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/InfoPlist.strings; sourceTree = "<group>"; };
DCEE05AD20C20D650081CD34 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Main.strings; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -119,6 +128,8 @@
DC56BDCF1E46DEB900AAD0D9 /* LaunchScreen.storyboard */, DC56BDCF1E46DEB900AAD0D9 /* LaunchScreen.storyboard */,
DC56BDD21E46DEB900AAD0D9 /* TGPControlsDemo-Pods-Info.plist */, DC56BDD21E46DEB900AAD0D9 /* TGPControlsDemo-Pods-Info.plist */,
DC4FF6511EA2E08C00BBF8E4 /* TGPControlsDemo-Cart-Info.plist */, DC4FF6511EA2E08C00BBF8E4 /* TGPControlsDemo-Cart-Info.plist */,
DC7677B620C5C5BA006155F3 /* Localizable.strings */,
DC7677BB20C5C712006155F3 /* InfoPlist.strings */,
); );
path = TGPControlsDemo; path = TGPControlsDemo;
sourceTree = "<group>"; sourceTree = "<group>";
@ -188,6 +199,7 @@
knownRegions = ( knownRegions = (
en, en,
Base, Base,
ar,
); );
mainGroup = DC56BDBA1E46DEB900AAD0D9; mainGroup = DC56BDBA1E46DEB900AAD0D9;
productRefGroup = DC56BDC41E46DEB900AAD0D9 /* Products */; productRefGroup = DC56BDC41E46DEB900AAD0D9 /* Products */;
@ -206,8 +218,10 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
DC4FF6481EA2E08C00BBF8E4 /* LaunchScreen.storyboard in Resources */, DC4FF6481EA2E08C00BBF8E4 /* LaunchScreen.storyboard in Resources */,
DC7677B920C5C5BA006155F3 /* Localizable.strings in Resources */,
DC4FF6491EA2E08C00BBF8E4 /* Assets.xcassets in Resources */, DC4FF6491EA2E08C00BBF8E4 /* Assets.xcassets in Resources */,
DC4FF64A1EA2E08C00BBF8E4 /* Main.storyboard in Resources */, DC4FF64A1EA2E08C00BBF8E4 /* Main.storyboard in Resources */,
DC7677BE20C5C712006155F3 /* InfoPlist.strings in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -216,8 +230,10 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
DC56BDD11E46DEB900AAD0D9 /* LaunchScreen.storyboard in Resources */, DC56BDD11E46DEB900AAD0D9 /* LaunchScreen.storyboard in Resources */,
DC7677B820C5C5BA006155F3 /* Localizable.strings in Resources */,
DC56BDCE1E46DEB900AAD0D9 /* Assets.xcassets in Resources */, DC56BDCE1E46DEB900AAD0D9 /* Assets.xcassets in Resources */,
DC56BDCC1E46DEB900AAD0D9 /* Main.storyboard in Resources */, DC56BDCC1E46DEB900AAD0D9 /* Main.storyboard in Resources */,
DC7677BD20C5C712006155F3 /* InfoPlist.strings in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -303,6 +319,7 @@
isa = PBXVariantGroup; isa = PBXVariantGroup;
children = ( children = (
DC56BDCB1E46DEB900AAD0D9 /* Base */, DC56BDCB1E46DEB900AAD0D9 /* Base */,
DCEE05AD20C20D650081CD34 /* ar */,
); );
name = Main.storyboard; name = Main.storyboard;
sourceTree = "<group>"; sourceTree = "<group>";
@ -315,6 +332,24 @@
name = LaunchScreen.storyboard; name = LaunchScreen.storyboard;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
DC7677B620C5C5BA006155F3 /* Localizable.strings */ = {
isa = PBXVariantGroup;
children = (
DC7677B720C5C5BA006155F3 /* Base */,
DC7677BA20C5C5E5006155F3 /* ar */,
);
name = Localizable.strings;
sourceTree = "<group>";
};
DC7677BB20C5C712006155F3 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
DC7677BC20C5C712006155F3 /* Base */,
DC7677BF20C5C769006155F3 /* ar */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */ /* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */ /* Begin XCBuildConfiguration section */
@ -332,7 +367,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.swiftarchitect.TGPControlsDemo; PRODUCT_BUNDLE_IDENTIFIER = com.swiftarchitect.TGPControlsDemo;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0; SWIFT_VERSION = 4.0;
}; };
name = Debug; name = Debug;
}; };
@ -350,7 +385,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.swiftarchitect.TGPControlsDemo; PRODUCT_BUNDLE_IDENTIFIER = com.swiftarchitect.TGPControlsDemo;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0; SWIFT_VERSION = 4.0;
}; };
name = Release; name = Release;
}; };
@ -359,6 +394,7 @@
buildSettings = { buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)";
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++"; CLANG_CXX_LIBRARY = "libc++";
@ -409,6 +445,7 @@
SDKROOT = iphoneos; SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
}; };
name = Debug; name = Debug;
@ -418,6 +455,7 @@
buildSettings = { buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)";
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++"; CLANG_CXX_LIBRARY = "libc++";
@ -460,6 +498,7 @@
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES; VALIDATE_PRODUCT = YES;
}; };

View File

@ -0,0 +1,2 @@
"CFBundleDisplayName" = "TGPControls";
"NSHumanReadableCopyright" = "2016 Xavier Schott";

View File

@ -0,0 +1,15 @@
"oneTo10Labels.numbers" = "1 2 3 4 5 6 7 8 9 10";
"alphabetLabels.letters" = "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z";
"pictureLabels.east" = "orient";
"pictureLabels.west" = "occident";
"pictureLabels.up" = "zénith";
"pictureLabels.down" = "nadir";
"pictureLabels.north" = "septentrion";
"pictureLabels.south" = "midi";
"switch1Camel.off" = "OFF";
"switch1Camel.on" = "ON";
"switch2Camel.off" = "O";
"switch2Camel.on" = "l";

View File

@ -4,6 +4,8 @@
<dict> <dict>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>en</string> <string>en</string>
<key>CFBundleDisplayName</key>
<string>TGPControls</string>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string> <string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
@ -15,7 +17,7 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>4.0.0</string> <string>5.0.3</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1</string> <string>1</string>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>

View File

@ -4,6 +4,8 @@
<dict> <dict>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>en</string> <string>en</string>
<key>CFBundleDisplayName</key>
<string>TGPControls</string>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string> <string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
@ -15,7 +17,7 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>4.0.0</string> <string>5.0.3</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1</string> <string>1</string>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>

View File

@ -18,14 +18,35 @@ class ViewController: UIViewController {
@IBOutlet weak var dualColorSlider: TGPDiscreteSlider! @IBOutlet weak var dualColorSlider: TGPDiscreteSlider!
@IBOutlet weak var stepper: UIStepper! @IBOutlet weak var stepper: UIStepper!
private func localizedStrings(_ key: String) -> [String] {
return NSLocalizedString(key, comment: "")
.split(separator: " ")
.map({ (substring) -> String in
return "\(substring)"
})
}
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
alphabetLabels.names = ["A","B","C","D","E","F", "G","H","I","J","K","L","M", oneTo10Labels.names = localizedStrings("oneTo10Labels.numbers")
"N","O","P","Q","R","S", "T","U","V","W","X","Y","Z"]
pictureLabels.names = ["orient", "occident", "zénith", "nadir", "septentrion", "midi"] alphabetLabels.names = localizedStrings("alphabetLabels.letters")
switch1Camel.names = ["OFF", "ON"] alphabetSlider.tickCount = alphabetLabels.names.count // Number of letters in the given alphabet
switch2Camel.names = ["O", "l"]
pictureLabels.names = [NSLocalizedString("pictureLabels.east", comment: ""),
NSLocalizedString("pictureLabels.west", comment: ""),
NSLocalizedString("pictureLabels.up", comment: ""),
NSLocalizedString("pictureLabels.down", comment: ""),
NSLocalizedString("pictureLabels.north", comment: ""),
NSLocalizedString("pictureLabels.south", comment: "")]
switch1Camel.names = [NSLocalizedString("switch1Camel.off", comment: ""),
NSLocalizedString("switch1Camel.on", comment: "")]
switch2Camel.names = [NSLocalizedString("switch2Camel.off", comment: ""),
NSLocalizedString("switch2Camel.on", comment: "")]
// Automatically track tick spacing changes and UIControlEventValueChanged // Automatically track tick spacing changes and UIControlEventValueChanged
alphabetSlider.ticksListener = alphabetLabels alphabetSlider.ticksListener = alphabetLabels

View File

@ -0,0 +1,2 @@
"CFBundleDisplayName" = "مراقبةTGP";
"NSHumanReadableCopyright" = "2016 Xavier Schott";

View File

@ -0,0 +1,15 @@
"oneTo10Labels.numbers" = "١ ٢ ٣ ٤ ٥ ٦ ٧ ٨ ٩ ١٠";
"alphabetLabels.letters" = "ا ب ج د ه و ز ح ط ي ك ل م ن س ع ف ص ق ر ش ت ث خ ذ ض ظ غ";
"pictureLabels.east" = "الشرق";
"pictureLabels.west" = "غرب";
"pictureLabels.up" = "إلى فوق";
"pictureLabels.down" = "نزولا";
"pictureLabels.north" = "شمال";
"pictureLabels.south" = "جنوب";
"switch1Camel.off" = "اطفاء";
"switch1Camel.on" = "تشغيل";
"switch2Camel.off" = "٠";
"switch2Camel.on" = "١";

View File

@ -0,0 +1,15 @@
/* Class = "UILabel"; text = "Layers and transparency"; ObjectID = "1wG-kf-nie"; */
"1wG-kf-nie.text" = "Layers and transparency";
/* Class = "UILabel"; text = "CamelLabels + Switch"; ObjectID = "A6t-OF-SSy"; */
"A6t-OF-SSy.text" = "CamelLabels + Switch";
/* Class = "UILabel"; text = "Variations"; ObjectID = "XPd-Af-CYy"; */
"XPd-Af-CYy.text" = "Variations";
/* Class = "UILabel"; text = "UIControlActions"; ObjectID = "gID-5d-KDe"; */
"gID-5d-KDe.text" = "UIControlActions";
/* Class = "UILabel"; text = "DiscreteSlider + CamelLabels"; ObjectID = "hED-uQ-kcm"; */
"hED-uQ-kcm.text" = "DiscreteSlider + CamelLabels";