├── .clang-format-ci
├── .gitignore
├── .kokoro
├── .travis.yml
├── BUILD
├── CHANGELOG.md
├── CODEOWNERS
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Examples
├── Flags.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
└── Flags
│ ├── Default-568h@2x.png
│ ├── Flags.xcodeproj
│ ├── project.pbxproj
│ └── xcshareddata
│ │ └── xcschemes
│ │ ├── Flags.xcscheme
│ │ └── FlagsUITests.xcscheme
│ ├── FlagsUITests
│ ├── FlagsUITests.m
│ └── Info.plist
│ └── MDFInternationalizationExample
│ ├── AppDelegate.h
│ ├── AppDelegate.m
│ ├── AppIcon
│ ├── appicon-20@2x.png
│ ├── appicon-20@3x.png
│ ├── appicon-29@2x.png
│ ├── appicon-29@3x.png
│ ├── appicon-40@2x.png
│ ├── appicon-40@3x.png
│ ├── appicon-60@2x.png
│ └── appicon-60@3x.png
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ ├── AppIcon-1024.png
│ │ ├── Contents.json
│ │ ├── appicon-20@2x.png
│ │ ├── appicon-20@3x.png
│ │ ├── appicon-29@2x.png
│ │ ├── appicon-29@3x.png
│ │ ├── appicon-40@2x.png
│ │ ├── appicon-40@3x.png
│ │ ├── appicon-60@2x.png
│ │ └── appicon-60@3x.png
│ ├── BidiIcon.imageset
│ │ ├── Contents.json
│ │ ├── baseline_compare_arrows_black_36pt_1x.png
│ │ ├── baseline_compare_arrows_black_36pt_2x.png
│ │ └── baseline_compare_arrows_black_36pt_3x.png
│ ├── BigAppIcon.imageset
│ │ ├── BigAppIcon.png
│ │ └── Contents.json
│ ├── Contents.json
│ ├── FlagIcon.imageset
│ │ ├── Contents.json
│ │ ├── ic_flag_36pt.png
│ │ ├── ic_flag_36pt_2x.png
│ │ └── ic_flag_36pt_3x.png
│ ├── InfoIcon.imageset
│ │ ├── Contents.json
│ │ ├── ic_info_36pt.png
│ │ ├── ic_info_36pt_2x.png
│ │ └── ic_info_36pt_3x.png
│ ├── Nonspeaking.imageset
│ │ ├── Contents.json
│ │ ├── ic_hearing_white_48pt.png
│ │ ├── ic_hearing_white_48pt_2x.png
│ │ └── ic_hearing_white_48pt_3x.png
│ ├── Speaking.imageset
│ │ ├── Contents.json
│ │ ├── ic_hearing_48pt.png
│ │ ├── ic_hearing_48pt_2x.png
│ │ └── ic_hearing_48pt_3x.png
│ └── Standard.imageset
│ │ ├── Contents.json
│ │ └── LtoR.png
│ ├── Attic
│ ├── ARG.png
│ ├── AUS.png
│ ├── AppIcon-1024.png
│ ├── BTN.png
│ ├── BigAppIcon.png
│ ├── CAN.png
│ ├── FRA.png
│ ├── Flag_of_Argentina.svg
│ ├── Flag_of_Australia_(converted).svg
│ ├── Flag_of_Bhutan.svg
│ ├── Flag_of_Canada.svg
│ ├── Flag_of_France.svg
│ ├── Flag_of_Greece.svg
│ ├── Flag_of_India.svg
│ ├── Flag_of_Jamaica.svg
│ ├── Flag_of_Japan.svg
│ ├── Flag_of_Mexico.svg
│ ├── Flag_of_Nepal.svg
│ ├── Flag_of_Papua_New_Guinea.svg
│ ├── Flag_of_Qatar.svg
│ ├── Flag_of_Slovakia.svg
│ ├── Flag_of_South_Africa.svg
│ ├── Flag_of_Tunisia.svg
│ ├── Flag_of_Zambia.svg
│ ├── Flag_of_the_United_States.svg
│ ├── GRC.png
│ ├── IND.png
│ ├── JAM.png
│ ├── JPN.png
│ ├── MEX.png
│ ├── NPL.png
│ ├── PNG.png
│ ├── QAT.png
│ ├── SVK.png
│ ├── TUN.png
│ ├── USA.png
│ ├── ZAF.png
│ ├── ZMB.png
│ ├── ic_flag_black_1024.png
│ ├── ic_flag_black_48px.svg
│ ├── ic_hearing_black_48dp
│ │ ├── ic_hearing_48pt.png
│ │ ├── ic_hearing_48pt_2x.png
│ │ └── ic_hearing_48pt_3x.png
│ ├── ic_hearing_black_48px.svg
│ └── ic_hearing_grey_48dp
│ │ ├── ic_hearing_grey_48pt.png
│ │ ├── ic_hearing_grey_48pt_2x.png
│ │ └── ic_hearing_grey_48pt_3x.png
│ ├── Base.lproj
│ ├── Countries.strings
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── BidirectionalViewController.h
│ ├── BidirectionalViewController.m
│ ├── CountryCell.h
│ ├── CountryCell.m
│ ├── CountryTableViewController.h
│ ├── CountryTableViewController.m
│ ├── Flags.xcassets
│ ├── ARG.imageset
│ │ ├── ARG.png
│ │ └── Contents.json
│ ├── AUS.imageset
│ │ ├── AUS.png
│ │ └── Contents.json
│ ├── BTN.imageset
│ │ ├── BTN.png
│ │ └── Contents.json
│ ├── CAN.imageset
│ │ ├── CAN.png
│ │ └── Contents.json
│ ├── Contents.json
│ ├── FRA.imageset
│ │ ├── Contents.json
│ │ └── FRA.png
│ ├── GRC.imageset
│ │ ├── Contents.json
│ │ └── GRC.png
│ ├── IND.imageset
│ │ ├── Contents.json
│ │ └── IND.png
│ ├── JAM.imageset
│ │ ├── Contents.json
│ │ └── JAM.png
│ ├── JPN.imageset
│ │ ├── Contents.json
│ │ └── JPN.png
│ ├── MEX.imageset
│ │ ├── Contents.json
│ │ └── MEX.png
│ ├── NPL.imageset
│ │ ├── Contents.json
│ │ └── NPL.png
│ ├── PNG.imageset
│ │ ├── Contents.json
│ │ └── PNG.png
│ ├── QAT.imageset
│ │ ├── Contents.json
│ │ └── QAT.png
│ ├── SVK.imageset
│ │ ├── Contents.json
│ │ └── SVK.png
│ ├── TUN.imageset
│ │ ├── Contents.json
│ │ └── TUN.png
│ ├── USA.imageset
│ │ ├── Contents.json
│ │ └── USA.png
│ ├── ZAF.imageset
│ │ ├── Contents.json
│ │ └── ZAF.png
│ └── ZMB.imageset
│ │ ├── Contents.json
│ │ └── ZMB.png
│ ├── Info.plist
│ ├── InformationViewController.h
│ ├── InformationViewController.m
│ ├── ar.lproj
│ ├── Countries.strings
│ ├── InfoPlist.strings
│ └── Main.strings
│ ├── en.lproj
│ ├── Countries.strings
│ ├── Info.plist
│ ├── InfoPlist.strings
│ └── Main.strings
│ └── main.m
├── LICENSE
├── MDFInternationalization.podspec
├── MDFInternationalization.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
├── xcshareddata
│ └── xcschemes
│ │ ├── MDFInternationalization.xcscheme
│ │ └── MDFInternationalizationTests.xcscheme
└── xcuserdata
│ └── iangordon.xcuserdatad
│ └── xcschemes
│ └── xcschememanagement.plist
├── README.md
├── Sources
├── Info.plist
├── MDFInternationalization.h
├── MDFRTL.h
├── MDFRTL.m
├── NSLocale+MaterialRTL.h
├── NSLocale+MaterialRTL.m
├── NSString+MaterialBidi.h
├── NSString+MaterialBidi.m
├── UIImage+MaterialRTL.h
├── UIImage+MaterialRTL.m
├── UIView+MaterialRTL.h
└── UIView+MaterialRTL.m
├── Tests
├── Info.plist
├── MDFBidiTests.m
├── MDFInternationalizationTests.m
└── MDFRTLTests.m
├── WORKSPACE
└── apple_framework_relative_headers.bzl
/.clang-format-ci:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright 2018-present The Material Foundation Authors. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | # Fail on any error.
18 | set -e
19 |
20 | REPO="material-foundation/material-internationalization-ios"
21 |
22 | # The tagged version of https://github.com/material-foundation/clang-format-ci to check out.
23 | # A * wildcard can be used to check out the latest release of a given version.
24 | CLANG_FORMAT_CI_VERSION="v1.*"
25 |
26 | CLANG_FORMAT_CI_SRC_DIR=".clang-format-ci-src"
27 |
28 | # Will run git clang-format on the branch's changes, reporting a failure if the linter generated any
29 | # stylistic changes.
30 | #
31 | # For local runs, you must set the following environment variables:
32 | #
33 | # GITHUB_API_TOKEN -> Create a token here: https://github.com/settings/tokens.
34 | # Must have public_repo scope.
35 | # KOKORO_GITHUB_PULL_REQUEST_NUMBER="###" -> The PR # you want to post the API diff results to.
36 | # KOKORO_GITHUB_PULL_REQUEST_COMMIT="..." -> The PR commit you want to post to.
37 | #
38 | # And install the following tools:
39 | #
40 | # - clang-format
41 | # - git-clang-format
42 | lint_clang_format() {
43 | if [ ! -d "$CLANG_FORMAT_CI_SRC_DIR" ]; then
44 | git clone --recurse-submodules https://github.com/material-foundation/clang-format-ci.git "$CLANG_FORMAT_CI_SRC_DIR"
45 | fi
46 |
47 | pushd "$CLANG_FORMAT_CI_SRC_DIR"
48 | git fetch > /dev/null
49 | TAG=$(git tag --sort=v:refname -l "$CLANG_FORMAT_CI_VERSION" | tail -n1)
50 | git checkout "$TAG" > /dev/null
51 | git submodule update --init --recursive
52 | echo "Using clang-format-ci $TAG"
53 | popd
54 |
55 | .clang-format-ci-src/from-kokoro.sh "$REPO"
56 | }
57 |
58 | lint_clang_format
59 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | bazel-*
2 | .kokoro-ios-runner
3 | .clang-format-ci-src
4 |
5 | # Xcode
6 | #
7 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
8 |
9 | # OS X System files
10 | .DS_Store
11 |
12 | ## Build generated
13 | build/
14 | DerivedData/
15 |
16 | ## Various settings
17 | *.pbxuser
18 | !default.pbxuser
19 | *.mode1v3
20 | !default.mode1v3
21 | *.mode2v3
22 | !default.mode2v3
23 | *.perspectivev3
24 | !default.perspectivev3
25 | xcuserdata/
26 |
27 | ## Other
28 | *.moved-aside
29 | *.xcuserstate
30 |
31 | ## Obj-C/Swift specific
32 | *.hmap
33 | *.ipa
34 | *.dSYM.zip
35 | *.dSYM
36 |
37 | # CocoaPods
38 | #
39 | # We recommend against adding the Pods directory to your .gitignore. However
40 | # you should judge for yourself, the pros and cons are mentioned at:
41 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
42 | #
43 | Pods/
44 |
45 | # Carthage
46 | #
47 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
48 | # Carthage/Checkouts
49 |
50 | Carthage/Build
51 |
52 | # fastlane
53 | #
54 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
55 | # screenshots whenever they are needed.
56 | # For more information about the recommended setup visit:
57 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
58 |
59 | fastlane/report.xml
60 | fastlane/screenshots
61 |
62 | # Code Injection
63 | #
64 | # After new code Injection tools there's a generated folder /iOSInjectionProject
65 | # https://github.com/johnno1962/injectionforxcode
66 |
67 | iOSInjectionProject/
--------------------------------------------------------------------------------
/.kokoro:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright 2017-present The Material Foundation Authors. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | # Fail on any error.
18 | set -e
19 |
20 | # Display commands to stderr.
21 | set -x
22 |
23 | KOKORO_RUNNER_VERSION="v3.*"
24 |
25 | if [ ! -d .kokoro-ios-runner ]; then
26 | git clone https://github.com/material-foundation/kokoro-ios-runner.git .kokoro-ios-runner
27 | fi
28 |
29 | pushd .kokoro-ios-runner
30 | git fetch > /dev/null
31 | TAG=$(git tag --sort=v:refname -l "$KOKORO_RUNNER_VERSION" | tail -n1)
32 | git checkout "$TAG" > /dev/null
33 | popd
34 |
35 | if [ -n "$KOKORO_BUILD_NUMBER" ]; then
36 | bazel version
37 | use_bazel.sh 1.1.0
38 | bazel version
39 | fi
40 |
41 | ./.kokoro-ios-runner/bazel.sh test //:UnitTests --min-xcode-version 9.0
42 |
43 | echo "Success!"
44 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: objective-c
2 | sudo: false
3 |
4 | # Only do a shallow clone of our Git repo.
5 | # https://docs.travis-ci.com/user/customizing-the-build#Git-Clone-Depth
6 | git:
7 | depth: 3
8 |
9 | # Only fire off builds for specific branches.
10 | branches:
11 | only:
12 | - develop
13 | - stable
14 | - /^feature-.*$/
15 | - release-candidate
16 |
17 | xcode_project: MDFInternationalization.xcodeproj
18 | xcode_scheme: MDFInternationalizationTests
19 |
20 | matrix:
21 | include:
22 | - osx_image: xcode9
23 | # The iPhone X was chosen because it is a device with a strange screen size and
24 | # the 'notch'.
25 | # OS 11.0 was chosen as the latest generally available iOS version.
26 | env: DESTINATION="platform=iOS Simulator,name=iPhone X,OS=11.0" SDK="iphonesimulator11.0"
27 | - osx_image: xcode9
28 | # The iPhone 7 Plus was chosen because it is a device with a 3x screen and also changes
29 | # its size category trait on rotation.
30 | # OS 10.3.1 was chosen to represent iOS 10.
31 | env: DESTINATION="platform=iOS Simulator,name=iPhone 7 Plus,OS=10.3.1" SDK="iphonesimulator11.0"
32 | - osx_image: xcode8.3
33 | # The iPad Pro 12.9 was chosen because it is the largest resolution we can test on.
34 | # OS 9.3 was chosen to round out the range of iOS versions we are testing on.
35 | env: DESTINATION="platform=iOS Simulator,name=iPad Pro (12.9-inch),OS=9.3" SDK="iphonesimulator10.3"
36 | - osx_image: xcode8.3
37 | # The iPhone 5 was chosen because it is a 32-bit device.
38 | # OS 8.1 was chosen because it is the earliest iOS offered here.
39 | env: DESTINATION="platform=iOS Simulator,name=iPhone 5,OS=8.1" SDK="iphonesimulator10.3"
40 |
41 | # Test Execution
42 | # TODO Enable set -euo pipefail
43 | script:
44 | - env
45 | - set -o pipefail
46 | - echo xcodebuild -project "$TRAVIS_XCODE_PROJECT" -scheme "$TRAVIS_XCODE_SCHEME" -sdk "$SDK" -destination "$DESTINATION" test
47 | - xcodebuild -project "$TRAVIS_XCODE_PROJECT" -scheme "$TRAVIS_XCODE_SCHEME" -sdk "$SDK" -destination "$DESTINATION" test | xcpretty
--------------------------------------------------------------------------------
/BUILD:
--------------------------------------------------------------------------------
1 | # Copyright 2017-present The Material Foundation Authors. All Rights Reserved.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | load("@bazel_skylib//rules:build_test.bzl", "build_test")
16 | load("@build_bazel_rules_apple//apple:ios.bzl", "ios_unit_test_suite")
17 | load("@build_bazel_rules_apple//apple/testing/default_runner:ios_test_runner.bzl", "ios_test_runner")
18 | load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
19 | load("@bazel_ios_warnings//:strict_warnings_objc_library.bzl", "strict_warnings_objc_library")
20 | load(":apple_framework_relative_headers.bzl", "apple_framework_relative_headers")
21 |
22 | licenses(["notice"]) # Apache 2.0
23 |
24 | exports_files(["LICENSE"])
25 |
26 | strict_warnings_objc_library(
27 | name = "MDFInternationalization",
28 | srcs = glob([
29 | "Sources/*.m",
30 | ]),
31 | hdrs = glob([
32 | "Sources/*.h",
33 | ]),
34 | sdk_frameworks = [
35 | "UIKit",
36 | "CoreGraphics",
37 | "CoreImage",
38 | ],
39 | enable_modules = 1,
40 | includes = ["Sources"],
41 | visibility = ["//visibility:public"],
42 | deps = [
43 | ":MDFInternationalizationFrameworkHeaders",
44 | ],
45 | )
46 |
47 | apple_framework_relative_headers(
48 | name = "MDFInternationalizationFrameworkHeaders",
49 | hdrs = glob([
50 | "Sources/*.h",
51 | ]),
52 | framework_name = "MDFInternationalization",
53 | )
54 |
55 | build_test(
56 | name = "BuildTest",
57 | targets = [
58 | ":MDFInternationalization"
59 | ],
60 | )
61 |
62 | objc_library(
63 | name = "UnitTestsLib",
64 | srcs = glob([
65 | "Tests/*.m",
66 | ]),
67 | deps = [
68 | ":MDFInternationalization",
69 | ":MDFInternationalizationFrameworkHeaders",
70 | ],
71 | )
72 |
73 | ios_test_runner(
74 | name = "IPAD_PRO_12_9_IN_9_3",
75 | device_type = "iPad Pro (12.9-inch)",
76 | os_version = "9.3",
77 | )
78 |
79 | ios_test_runner(
80 | name = "IPHONE_7_PLUS_IN_10_3",
81 | device_type = "iPhone 7 Plus",
82 | os_version = "10.3",
83 | )
84 |
85 | ios_test_runner(
86 | name = "IPHONE_X_IN_11_4",
87 | device_type = "iPhone X",
88 | os_version = "11.4",
89 | )
90 |
91 | ios_test_runner(
92 | name = "IPHONE_XS_MAX_IN_12_2",
93 | device_type = "iPhone Xs Max",
94 | os_version = "12.2",
95 | )
96 |
97 | ios_unit_test_suite(
98 | name = "UnitTests",
99 | deps = [
100 | ":UnitTestsLib",
101 | ],
102 | minimum_os_version = "9.0",
103 | timeout = "short",
104 | runners = [
105 | ":IPAD_PRO_12_9_IN_9_3",
106 | ":IPHONE_7_PLUS_IN_10_3",
107 | ":IPHONE_X_IN_11_4",
108 | ":IPHONE_XS_MAX_IN_12_2",
109 | ],
110 | )
111 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # 3.0.0
2 |
3 | This major release drops support for iOS 9 and 10.
4 |
5 | # 2.0.1
6 |
7 | This patch release fixes framework-style imports when using bazel to build this library as an
8 | external dependency.
9 |
10 | ## Non-source changes
11 |
12 | * [Add workspace_root to framework import path. (#51)](https://github.com/material-foundation/material-internationalization-ios/commit/25a16214c9ca8ecfbb89f4168f7967c3a0549921) (featherless)
13 |
14 | # 2.0.0
15 |
16 | This major release upgrades the bazel dependencies and workspace. This change is breaking for anyone
17 | using bazel to build this library. In order to use this library with bazel, you will also need to
18 | upgrade your workspace versions to match the ones now used in this library's `WORKSPACE` file.
19 |
20 | * [Update bazel workspace to latest versions. (#49)](https://github.com/material-foundation/material-internationalization-ios/commit/2ff10388f4a61c16a856092cdfba709ddbcdd2eb) (featherless)
21 |
22 | # 1.1.1
23 |
24 | * [Add MDFInternationalizationFrameworkHeaders as a dependency for bazel. (#47)](https://github.com/material-foundation/material-internationalization-ios/commit/580082c633f1e1146fd0634f02dcf39270c5375a) (featherless)
25 | * [Integrate clang-format-ci. (#45)](https://github.com/material-foundation/material-internationalization-ios/commit/3ec6a305948a1bdac426e10811afbec691065341) (featherless)
26 | * [Update to latest Xcode](https://github.com/material-foundation/material-internationalization-ios/commit/eb2107d3208f045d6464115f3cb5453d06a9c243) (Ian Gordon)
27 | * [Update README.md](https://github.com/material-foundation/material-internationalization-ios/commit/39955811b952cc7a2f37201faeb38eeb3a239636) (ianegordon)
28 |
29 | # 1.1.0
30 |
31 | * [Add Bidi utilities (#42)](https://github.com/material-foundation/material-internationalization-ios/pull/42) (Ian Gordon)
32 | * [Add support for relative paths to the Bazel build](https://github.com/material-foundation/material-internationalization-ios/pull/41) (Ian Gordon)
33 | * [Bazel specific import paths are no longer required.](https://github.com/material-foundation/material-internationalization-ios/pull/38) (dmaclach)
34 | * [Silence warnings (#37)](https://github.com/material-foundation/material-internationalization-ios/pull/37) (Ian Gordon)
35 |
36 | # 1.0.4
37 |
38 | * [[Bazel] Fix BUILD file SDK dependencies (#36)](https://github.com/material-components/material-components-ios/commit/298b51d3523a346a404e7e8c8bda14e27ed65226) (Robert Moore)
39 |
40 | # 1.0.3
41 |
42 | * [Add compile time flag for import style (#34)](https://github.com/material-foundation/material-internationalization-ios/88af44b587cb03408a827b97aa82234f6a7abc23) (ianegordon)
43 | * [Add C++ guards so the compiler does not mangle symbol names. (#31)](https://github.com/material-foundation/material-internationalization-ios/5060976bcf45947d1176f8e060d13d4447b60a10) (Adrian Secord)
44 | * [Remove framework-style headers from the umbrella header. (#30)](https://github.com/material-foundation/material-internationalization-ios/fef1a31313a4a8aa0234cce416e1615c7054cf9d) (featherless)
45 | * [Add support for bazel and kokoro. (#27)](https://github.com/material-foundation/material-internationalization-ios/42a9bdf739a8de112fbcf8d395640f3477306fae) (featherless)
46 | * [Silence NSNumber to BOOL conversion analyzer warning (#28)](https://github.com/material-foundation/material-internationalization-ios/5630a566396477ce6df5fd48b885aefdf40826d6) (ianegordon)
47 | * [[RTL] Comment corrections and clarifications. (#26)](https://github.com/material-foundation/material-internationalization-ios/b6d5bfb53cac16de15c75d6571da5e15cdea4884) (Will Larche)
48 |
49 | # 1.0.2
50 |
51 | * [Update Project and Scheme to latest recommended settings](https://github.com/material-foundation/material-internationalization-ios/8a0317501403463fab8c1d541eddf0f649df2fc6) (Ian Gordon)
52 | * [Update Travis-CI build environments and simulators (#24)](https://github.com/material-foundation/material-internationalization-ios/25521a9733fea64a2c9cde737d1037d2ec5eee74) (ianegordon)
53 | * [Disable warnings added in Xcode 9 (#23)](https://github.com/material-foundation/material-internationalization-ios/6909be2fcde579116d7e454ae308dac777b740bb) (ianegordon)
54 |
55 | # 1.0.1
56 |
57 | * [Modify sharedApplication call to avoid extension error (#17)](https://github.com/material-foundation/material-internationalization-ios/commit/902e392e78c11e8ae5169135dd7a0077bcf37d48) (ianegordon)
58 |
59 | # 1.0.0
60 |
61 | Initial release.
62 |
63 |
--------------------------------------------------------------------------------
/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # This is a comment.
2 | # Each line is a file pattern followed by one or more owners.
3 |
4 | * @ianegordon
5 | * @arcank
6 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6 |
7 | ## Our Standards
8 |
9 | Examples of behavior that contributes to creating a positive environment include:
10 |
11 | * Using welcoming and inclusive language
12 | * Being respectful of differing viewpoints and experiences
13 | * Gracefully accepting constructive criticism
14 | * Focusing on what is best for the community
15 | * Showing empathy towards other community members
16 |
17 | Examples of unacceptable behavior by participants include:
18 |
19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances
20 | * Trolling, insulting/derogatory comments, and personal or political attacks
21 | * Public or private harassment
22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission
23 | * Other conduct which could reasonably be considered inappropriate in a professional setting
24 |
25 | ## Our Responsibilities
26 |
27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28 |
29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30 |
31 | ## Scope
32 |
33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34 |
35 | ## Enforcement
36 |
37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at mdc-coc@googlegroups.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38 |
39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40 |
41 | ## Attribution
42 |
43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
44 |
45 | [homepage]: http://contributor-covenant.org
46 | [version]: http://contributor-covenant.org/version/1/4/
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | Want to contribute? Great! First, read this page (including the [small print](#the-small-print)).
2 |
3 | ### Before you contribute
4 |
5 | Before we can use your code, you must sign the
6 | [Google Individual Contributor License Agreement](https://cla.developers.google.com/about/google-individual)
7 | (CLA), which you can do online. The CLA is necessary mainly because you own the copyright to your
8 | changes, even after your contribution becomes part of our codebase, so we need your permission to
9 | use and distribute your code. We also need to be sure of various other things—for instance that
10 | you'll tell us if you know that your code infringes on other people's patents. You don't have to
11 | sign the CLA until after you've submitted your code for review and a member has approved it, but you
12 | must do it before we can put your code into our codebase. Before you start working on a larger
13 | contribution, you should get in touch with us first through the issue tracker with your idea so that
14 | we can help out and possibly guide you. Coordinating up front makes it much easier to avoid
15 | frustration later on.
16 |
17 | ### Code reviews
18 |
19 | All submissions, including submissions by project members, require review. We use Github pull
20 | requests for this purpose.
21 |
22 | ### The small print
23 |
24 | Contributions made by corporations are covered by a different agreement than the one above, the
25 | [Software Grant and Corporate Contributor License Agreement](https://cla.developers.google.com/about/google-corporate).
26 |
27 |
--------------------------------------------------------------------------------
/Examples/Flags.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Examples/Flags.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Examples/Flags.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Examples/Flags/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/Default-568h@2x.png
--------------------------------------------------------------------------------
/Examples/Flags/Flags.xcodeproj/xcshareddata/xcschemes/Flags.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
43 |
49 |
50 |
51 |
52 |
53 |
59 |
60 |
61 |
62 |
63 |
64 |
74 |
76 |
82 |
83 |
84 |
85 |
86 |
87 |
93 |
95 |
101 |
102 |
103 |
104 |
106 |
107 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/Examples/Flags/Flags.xcodeproj/xcshareddata/xcschemes/FlagsUITests.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
14 |
15 |
17 |
23 |
24 |
25 |
26 |
27 |
33 |
34 |
35 |
36 |
37 |
38 |
48 |
49 |
50 |
51 |
57 |
58 |
60 |
61 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/Examples/Flags/FlagsUITests/FlagsUITests.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016-present Google Inc. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import
18 |
19 | @interface FlagsUITests : XCTestCase
20 |
21 | @end
22 |
23 | @implementation FlagsUITests
24 |
25 | - (void)setUp {
26 | [super setUp];
27 |
28 | // Put setup code here. This method is called before the invocation of each test method in the class.
29 |
30 | // In UI tests it is usually best to stop immediately when a failure occurs.
31 | self.continueAfterFailure = NO;
32 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
33 | [[[XCUIApplication alloc] init] launch];
34 |
35 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
36 | }
37 |
38 | - (void)tearDown {
39 | // Put teardown code here. This method is called after the invocation of each test method in the class.
40 | [super tearDown];
41 | }
42 |
43 | - (void)testAppStartup {
44 | // Use recording to get started writing UI tests.
45 | // Use XCTAssert and related functions to verify your tests produce the correct results.
46 | }
47 |
48 | - (void)testSimpleNavigation {
49 | // Use recording to get started writing UI tests.
50 | // Use XCTAssert and related functions to verify your tests produce the correct results.
51 |
52 | XCUIApplication *app = [[XCUIApplication alloc] init];
53 | XCUIElementQuery *tablesQuery = app.tables;
54 | [tablesQuery.staticTexts[@"Japan"] tap];
55 |
56 | XCUIElementQuery *tabBarsQuery = app.tabBars;
57 | [tabBarsQuery.buttons[@"Info"] tap];
58 | [tabBarsQuery.buttons[@"Flags"] tap];
59 | [tablesQuery.staticTexts[@"Mexico"] swipeUp];
60 | [tablesQuery.staticTexts[@"United States of America"] tap];
61 | [tablesQuery.staticTexts[@"Slovakia"] tap];
62 | }
63 |
64 | @end
65 |
--------------------------------------------------------------------------------
/Examples/Flags/FlagsUITests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/AppDelegate.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016-present Google Inc. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import
18 |
19 | @interface AppDelegate : UIResponder
20 |
21 | @property (strong, nonatomic) UIWindow *window;
22 |
23 | @end
24 |
25 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/AppDelegate.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016-present Google Inc. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import "AppDelegate.h"
18 |
19 | #import "CountryTableViewController.h"
20 |
21 | @interface AppDelegate ()
22 |
23 | @end
24 |
25 | @implementation AppDelegate
26 |
27 | - (BOOL)application:(UIApplication *)application
28 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
29 | // Allow playback so country names can be spoken over the main speaker
30 | NSError *error;
31 | [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&error];
32 | if (error) {
33 | NSLog(@"Error setting the category on AVAudioSession");
34 | }
35 |
36 | return YES;
37 | }
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/AppIcon/appicon-20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/AppIcon/appicon-20@2x.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/AppIcon/appicon-20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/AppIcon/appicon-20@3x.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/AppIcon/appicon-29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/AppIcon/appicon-29@2x.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/AppIcon/appicon-29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/AppIcon/appicon-29@3x.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/AppIcon/appicon-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/AppIcon/appicon-40@2x.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/AppIcon/appicon-40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/AppIcon/appicon-40@3x.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/AppIcon/appicon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/AppIcon/appicon-60@2x.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/AppIcon/appicon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/AppIcon/appicon-60@3x.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "appicon-20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "appicon-20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "appicon-29@2x.png",
19 | "scale" : "2x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "appicon-29@3x.png",
25 | "scale" : "3x"
26 | },
27 | {
28 | "size" : "40x40",
29 | "idiom" : "iphone",
30 | "filename" : "appicon-40@2x.png",
31 | "scale" : "2x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "appicon-40@3x.png",
37 | "scale" : "3x"
38 | },
39 | {
40 | "size" : "60x60",
41 | "idiom" : "iphone",
42 | "filename" : "appicon-60@2x.png",
43 | "scale" : "2x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "appicon-60@3x.png",
49 | "scale" : "3x"
50 | },
51 | {
52 | "size" : "1024x1024",
53 | "idiom" : "ios-marketing",
54 | "filename" : "AppIcon-1024.png",
55 | "scale" : "1x"
56 | }
57 | ],
58 | "info" : {
59 | "version" : 1,
60 | "author" : "xcode"
61 | }
62 | }
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/AppIcon.appiconset/appicon-20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/AppIcon.appiconset/appicon-20@2x.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/AppIcon.appiconset/appicon-20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/AppIcon.appiconset/appicon-20@3x.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/AppIcon.appiconset/appicon-29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/AppIcon.appiconset/appicon-29@2x.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/AppIcon.appiconset/appicon-29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/AppIcon.appiconset/appicon-29@3x.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/AppIcon.appiconset/appicon-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/AppIcon.appiconset/appicon-40@2x.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/AppIcon.appiconset/appicon-40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/AppIcon.appiconset/appicon-40@3x.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/AppIcon.appiconset/appicon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/AppIcon.appiconset/appicon-60@2x.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/AppIcon.appiconset/appicon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/AppIcon.appiconset/appicon-60@3x.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/BidiIcon.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "baseline_compare_arrows_black_36pt_1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "baseline_compare_arrows_black_36pt_2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "baseline_compare_arrows_black_36pt_3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/BidiIcon.imageset/baseline_compare_arrows_black_36pt_1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/BidiIcon.imageset/baseline_compare_arrows_black_36pt_1x.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/BidiIcon.imageset/baseline_compare_arrows_black_36pt_2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/BidiIcon.imageset/baseline_compare_arrows_black_36pt_2x.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/BidiIcon.imageset/baseline_compare_arrows_black_36pt_3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/BidiIcon.imageset/baseline_compare_arrows_black_36pt_3x.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/BigAppIcon.imageset/BigAppIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/BigAppIcon.imageset/BigAppIcon.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/BigAppIcon.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "BigAppIcon.png",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/FlagIcon.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "ic_flag_36pt.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "ic_flag_36pt_2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "ic_flag_36pt_3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/FlagIcon.imageset/ic_flag_36pt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/FlagIcon.imageset/ic_flag_36pt.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/FlagIcon.imageset/ic_flag_36pt_2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/FlagIcon.imageset/ic_flag_36pt_2x.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/FlagIcon.imageset/ic_flag_36pt_3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/FlagIcon.imageset/ic_flag_36pt_3x.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/InfoIcon.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "ic_info_36pt.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "ic_info_36pt_2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "ic_info_36pt_3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/InfoIcon.imageset/ic_info_36pt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/InfoIcon.imageset/ic_info_36pt.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/InfoIcon.imageset/ic_info_36pt_2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/InfoIcon.imageset/ic_info_36pt_2x.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/InfoIcon.imageset/ic_info_36pt_3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/InfoIcon.imageset/ic_info_36pt_3x.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/Nonspeaking.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "ic_hearing_white_48pt.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "ic_hearing_white_48pt_2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "ic_hearing_white_48pt_3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/Nonspeaking.imageset/ic_hearing_white_48pt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/Nonspeaking.imageset/ic_hearing_white_48pt.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/Nonspeaking.imageset/ic_hearing_white_48pt_2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/Nonspeaking.imageset/ic_hearing_white_48pt_2x.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/Nonspeaking.imageset/ic_hearing_white_48pt_3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/Nonspeaking.imageset/ic_hearing_white_48pt_3x.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/Speaking.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "ic_hearing_48pt.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "ic_hearing_48pt_2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "ic_hearing_48pt_3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/Speaking.imageset/ic_hearing_48pt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/Speaking.imageset/ic_hearing_48pt.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/Speaking.imageset/ic_hearing_48pt_2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/Speaking.imageset/ic_hearing_48pt_2x.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/Speaking.imageset/ic_hearing_48pt_3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/Speaking.imageset/ic_hearing_48pt_3x.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/Standard.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LtoR.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/Standard.imageset/LtoR.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Assets.xcassets/Standard.imageset/LtoR.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/ARG.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Attic/ARG.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/AUS.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Attic/AUS.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/AppIcon-1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Attic/AppIcon-1024.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/BTN.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Attic/BTN.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/BigAppIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Attic/BigAppIcon.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/CAN.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Attic/CAN.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/FRA.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Attic/FRA.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/Flag_of_Argentina.svg:
--------------------------------------------------------------------------------
1 |
2 |
35 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/Flag_of_Australia_(converted).svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/Flag_of_Canada.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/Flag_of_France.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/Flag_of_Greece.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/Flag_of_India.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/Flag_of_Jamaica.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/Flag_of_Japan.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/Flag_of_Nepal.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/Flag_of_Papua_New_Guinea.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/Flag_of_Qatar.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/Flag_of_Slovakia.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/Flag_of_South_Africa.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/Flag_of_Tunisia.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/Flag_of_the_United_States.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/GRC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Attic/GRC.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/IND.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Attic/IND.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/JAM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Attic/JAM.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/JPN.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Attic/JPN.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/MEX.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Attic/MEX.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/NPL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Attic/NPL.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/PNG.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Attic/PNG.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/QAT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Attic/QAT.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/SVK.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Attic/SVK.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/TUN.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Attic/TUN.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/USA.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Attic/USA.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/ZAF.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Attic/ZAF.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/ZMB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Attic/ZMB.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/ic_flag_black_1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Attic/ic_flag_black_1024.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/ic_flag_black_48px.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/ic_hearing_black_48dp/ic_hearing_48pt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Attic/ic_hearing_black_48dp/ic_hearing_48pt.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/ic_hearing_black_48dp/ic_hearing_48pt_2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Attic/ic_hearing_black_48dp/ic_hearing_48pt_2x.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/ic_hearing_black_48dp/ic_hearing_48pt_3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Attic/ic_hearing_black_48dp/ic_hearing_48pt_3x.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/ic_hearing_black_48px.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/ic_hearing_grey_48dp/ic_hearing_grey_48pt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Attic/ic_hearing_grey_48dp/ic_hearing_grey_48pt.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/ic_hearing_grey_48dp/ic_hearing_grey_48pt_2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Attic/ic_hearing_grey_48dp/ic_hearing_grey_48pt_2x.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Attic/ic_hearing_grey_48dp/ic_hearing_grey_48pt_3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Attic/ic_hearing_grey_48dp/ic_hearing_grey_48pt_3x.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Base.lproj/Countries.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Countries.strings
3 | MDFInternationalizationExample
4 |
5 | Created by Ian Gordon on 9/8/16.
6 | Copyright © 2016 Google. All rights reserved.
7 | */
8 |
9 | "ARG" = "Argentina";
10 | "AUS" = "Australia";
11 | "BTN" = "Bhutan";
12 | "CAN" = "Canada";
13 | "FRA" = "France";
14 | "GRC" = "Greece";
15 | "IND" = "India";
16 | "JAM" = "Jamaica";
17 | "JPN" = "Japan";
18 | "MEX" = "Mexico";
19 | "NPL" = "Nepal";
20 | "PNG" = "Papua New Guinea";
21 | "QAT" = "Qatar";
22 | "SVK" = "Slovakia";
23 | "TUN" = "Tunisia";
24 | "USA" = "United States of America";
25 | "ZAF" = "South Africa";
26 | "ZMB" = "Zambia";
27 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/BidirectionalViewController.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2018-present Google Inc. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import
18 |
19 | @interface BidirectionalViewController : UIViewController
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/BidirectionalViewController.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2018-present Google Inc. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import "BidirectionalViewController.h"
18 |
19 | #import "MDFInternationalization.h"
20 |
21 |
22 | static NSString *LTREmbedding = @"\u202a"; // left-to-right embedding
23 | static NSString *RTLEmbedding = @"\u202b"; // right-to-left embedding
24 | static NSString *BidiPopEmbedding = @"\u202c"; // pop directional embedding
25 |
26 | static NSString *LTRMark = @"\u200e"; // left-to-right mark
27 | static NSString *RTLMark = @"\u200f"; // right-to-left mark
28 |
29 | // The following only work on iOS 10+
30 | static NSString *LTRIsolate = @"\u2066"; // left-to-right isolate
31 | static NSString *RTLIsolate = @"\u2067"; // right-to-left isolate
32 | static NSString *FirstStrongIsolate = @"\u2068"; // first strong isolate
33 | static NSString *PopIsolate = @"\u2069"; // pop directional isolate
34 |
35 |
36 | @interface BidirectionalViewController ()
37 |
38 | @property (weak, nonatomic) IBOutlet UILabel *labelOne;
39 | @property (weak, nonatomic) IBOutlet UILabel *labelTwo;
40 | @property (weak, nonatomic) IBOutlet UILabel *labelThree;
41 | @property (weak, nonatomic) IBOutlet UILabel *labelFour;
42 | @property (weak, nonatomic) IBOutlet UILabel *labelFive;
43 |
44 | @end
45 |
46 | @implementation BidirectionalViewController
47 |
48 | - (void)viewDidLoad {
49 | [super viewDidLoad];
50 |
51 | // The following lines will display a (: if the markers are supported, ): if not.
52 | self.labelOne.text =
53 | [NSString stringWithFormat:@"Bidi Isolate supported %@)%@:", RTLIsolate, PopIsolate];
54 | self.labelTwo.text =
55 | [NSString stringWithFormat:@"Bidi Embed supported %@)%@:", RTLEmbedding, BidiPopEmbedding];
56 |
57 | // Format a restaurant reservation as [Name] [Number of attendees] @ [time]
58 | // NSString *restaurantName = @"Cancun"; // Latin script
59 | NSString *restaurantName = @"מסעדת מגדלנה במגדל"; // Hebrew script
60 | NSInteger attendees = 4;
61 | NSTimeInterval futureInterval = 60. * 112; // 60 seconds * 122 minutes
62 | NSDate *reservationTime = [NSDate dateWithTimeIntervalSinceNow:futureInterval];
63 | NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
64 | dateFormatter.dateStyle = NSDateFormatterNoStyle;
65 | dateFormatter.timeStyle = NSDateFormatterShortStyle;
66 | NSString *reservationTimeString = [dateFormatter stringFromDate:reservationTime];
67 |
68 | NSString *unwrappedString = [NSString stringWithFormat:@"%@ : %ld @ %@", restaurantName, attendees, reservationTimeString];
69 | self.labelFour.text = unwrappedString;
70 |
71 | // The same string after wrapping the name
72 | NSString *wrappedRestaurantName =
73 | [restaurantName mdf_stringWithStereoReset:NSLocaleLanguageDirectionRightToLeft
74 | context:NSLocaleLanguageDirectionLeftToRight];
75 | NSString *wrappedString = [NSString stringWithFormat:@"%@ : %ld @ %@", wrappedRestaurantName, attendees, reservationTimeString];
76 | self.labelFive.text = wrappedString;
77 |
78 | }
79 |
80 | @end
81 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/CountryCell.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016-present Google Inc. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import
18 |
19 | @interface CountryCell : UITableViewCell
20 |
21 | @property (weak, nonatomic) IBOutlet UIImageView *flagView;
22 | @property (weak, nonatomic) IBOutlet UILabel *nameLabel;
23 | @property (weak, nonatomic) IBOutlet UIImageView *speechIcon;
24 |
25 | @property (nonatomic, assign, getter=isSpeakingName) BOOL speakingName;
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/CountryCell.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016-present Google Inc. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import "CountryCell.h"
18 |
19 | #import "MDFInternationalization.h"
20 |
21 | @implementation CountryCell
22 |
23 | // Mirroring images could take a non-trivial amount of time to create, so we cache the images.
24 | static UIImage *sSpeakingIcon;
25 | static UIImage *sNonspeakingIcon;
26 |
27 | - (void)awakeFromNib {
28 | [super awakeFromNib];
29 |
30 | // A flag imageview should not be mirrored in Right-to-Left so we force the view to Left-to-Right.
31 | self.flagView.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight;
32 |
33 | // The speech indicator icon can be mirrored, so we keep the default of
34 | // UISemanticContentAttributeUnspecified.
35 | // self.speechIcon.semanticContentAttribute = UISemanticContentAttributeUnspecified;
36 |
37 | // Our country name label takes up the middle of our cell, but will automatically align the
38 | // text based on it's default textAlignment of NSTextAlignmentNatural. So we leave its
39 | // semanticContentAttribute value as the default UISemanticContentAttributeUnspecified.
40 | // self.nameLabel.semanticContentAttribute = UISemanticContentAttributeUnspecified;
41 |
42 | // Mirroring images could take a non-trivial amount of time, so we cache the resulting images.
43 | static dispatch_once_t onceToken;
44 | dispatch_once(&onceToken, ^{
45 | sSpeakingIcon = [UIImage imageNamed:@"Speaking"];
46 | sNonspeakingIcon = [UIImage imageNamed:@"Nonspeaking"];
47 | if (self.speechIcon.mdf_effectiveUserInterfaceLayoutDirection !=
48 | UIUserInterfaceLayoutDirectionLeftToRight) {
49 | sSpeakingIcon = [sSpeakingIcon mdf_imageWithHorizontallyFlippedOrientation];
50 | sNonspeakingIcon = [sNonspeakingIcon mdf_imageWithHorizontallyFlippedOrientation];
51 | }
52 | });
53 | }
54 |
55 | - (void)layoutSubviews {
56 | // We manually calculate the frames for the views in our country cell
57 | CGFloat flagWidth = ceil(CGRectGetWidth(self.bounds) * 0.25);
58 | CGFloat flagHeight = CGRectGetHeight(self.bounds);
59 | CGRect flagFrame = CGRectMake(0.0, 0.0, flagWidth, flagHeight);
60 | flagFrame = CGRectInset(flagFrame, 4.0, 4.0);
61 |
62 | CGFloat speakIconWidth = ceil(CGRectGetWidth(self.bounds) * 0.15);
63 | CGFloat speakIconHeight = CGRectGetHeight(self.bounds);
64 | CGRect speechIconFrame = CGRectMake(0.0, 0.0, speakIconWidth, speakIconHeight);
65 | speechIconFrame.origin.x = CGRectGetWidth(self.bounds) - CGRectGetWidth(speechIconFrame);
66 |
67 | CGFloat nameWidth =
68 | CGRectGetWidth(self.bounds) - CGRectGetWidth(flagFrame) - CGRectGetWidth(speechIconFrame);
69 | CGFloat nameHeight = CGRectGetHeight(self.bounds);
70 | CGRect nameFrame = CGRectMake(0.0, 0.0, nameWidth, nameHeight);
71 | nameFrame.origin.x = CGRectGetMaxX(flagFrame);
72 | nameFrame = CGRectInset(nameFrame, 4.0, 0.0);
73 |
74 | // Mirror the framges if we are in RightToLeft mode.
75 | if (self.mdf_effectiveUserInterfaceLayoutDirection != UIUserInterfaceLayoutDirectionLeftToRight) {
76 | flagFrame = MDFRectFlippedHorizontally(flagFrame, CGRectGetWidth(self.bounds));
77 | nameFrame = MDFRectFlippedHorizontally(nameFrame, CGRectGetWidth(self.bounds));
78 | speechIconFrame = MDFRectFlippedHorizontally(speechIconFrame, CGRectGetWidth(self.bounds));
79 | }
80 |
81 | // Set the view frames
82 | self.flagView.frame = flagFrame;
83 | self.nameLabel.frame = nameFrame;
84 | self.speechIcon.frame = speechIconFrame;
85 | }
86 |
87 | // Adjust our speech indicator if we are actively speaking the name of the country.
88 | - (void)setSpeakingName:(BOOL)speakingName {
89 | if (speakingName) {
90 | self.speechIcon.image = sSpeakingIcon;
91 | } else {
92 | self.speechIcon.image = sNonspeakingIcon;
93 | }
94 | }
95 |
96 | @end
97 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/CountryTableViewController.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016-present Google Inc. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import
18 | #import
19 |
20 | @interface CountryTableViewController : UITableViewController
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/CountryTableViewController.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016-present Google Inc. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import "CountryTableViewController.h"
18 |
19 | #import
20 |
21 | #import "CountryCell.h"
22 |
23 | @interface CountryTableViewController ()
24 |
25 | @end
26 |
27 | @implementation CountryTableViewController {
28 | NSArray *_countryCodes;
29 | NSMutableArray *_flagImages;
30 |
31 | AVSpeechSynthesizer *_speechSynthesizer;
32 | NSMutableArray *_speakingCellIndexes;
33 | }
34 |
35 | - (void)viewDidLoad {
36 | [super viewDidLoad];
37 |
38 | _countryCodes = @[ @"ARG", @"AUS", @"BTN", @"CAN", @"FRA", @"GRC", @"IND", @"JAM", @"JPN", @"MEX",
39 | @"NPL", @"PNG", @"QAT", @"SVK", @"TUN", @"USA", @"ZAF", @"ZMB" ];
40 |
41 | _flagImages = [[NSMutableArray alloc] initWithCapacity:_countryCodes.count];
42 | for (NSString *countryCode in _countryCodes) {
43 | UIImage *image = [UIImage imageNamed:countryCode];
44 | [_flagImages addObject:image];
45 | }
46 |
47 | _speakingCellIndexes = [[NSMutableArray alloc] init];
48 |
49 | _speechSynthesizer = [[AVSpeechSynthesizer alloc] init];
50 | _speechSynthesizer.delegate = self;
51 | }
52 |
53 | - (void)viewDidAppear:(BOOL)animated {
54 | [super viewDidAppear:animated];
55 | if (_speechSynthesizer.isPaused) {
56 | [_speechSynthesizer continueSpeaking];
57 | }
58 | }
59 |
60 | #pragma mark - UITableViewDataSource
61 |
62 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
63 | return 1;
64 | }
65 |
66 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
67 | return _countryCodes.count;
68 | }
69 |
70 | - (UITableViewCell *)tableView:(UITableView *)tableView
71 | cellForRowAtIndexPath:(NSIndexPath *)indexPath {
72 | // NOTE: The string below must match the prototype cell identifier in the storyboard
73 | CountryCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CountryCell"];
74 |
75 | NSString *countryCode = _countryCodes[indexPath.row];
76 | UIImage *flagImage = _flagImages[indexPath.row];
77 |
78 | // Country names are taken from the Countries.strings file
79 | NSString *name = NSLocalizedStringFromTable(countryCode, @"Countries", @"ISO3 Country Code");
80 |
81 | cell.nameLabel.text = name;
82 | cell.flagView.image = flagImage;
83 |
84 | NSIndexPath *speakingIndexPath = [_speakingCellIndexes firstObject];
85 | if ([speakingIndexPath isEqual:indexPath]) {
86 | cell.speakingName = YES;
87 | } else {
88 | cell.speakingName = NO;
89 | }
90 |
91 | return cell;
92 | }
93 |
94 | #pragma mark - UITableViewDelegate
95 |
96 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
97 | NSString *countryCode = _countryCodes[indexPath.row];
98 | NSString *name = NSLocalizedStringFromTable(countryCode, @"Countries", @"ISO3 Country Code");
99 |
100 | AVSpeechUtterance *utterance = [AVSpeechUtterance speechUtteranceWithString:name];
101 | [_speechSynthesizer speakUtterance:utterance];
102 |
103 | [_speakingCellIndexes addObject:indexPath];
104 | }
105 |
106 | #pragma mark - AVSpeechSynthesizerDelegate
107 |
108 | - (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer
109 | willSpeakRangeOfSpeechString:(NSRange)characterRange
110 | utterance:(AVSpeechUtterance *)utterance {
111 | NSIndexPath *indexPath = [_speakingCellIndexes firstObject];
112 | if (indexPath && [self.tableView.indexPathsForVisibleRows containsObject:indexPath]) {
113 | CountryCell *cell =
114 | (CountryCell *)[self tableView:self.tableView cellForRowAtIndexPath:indexPath];
115 | cell.speakingName = YES;
116 |
117 | [self.tableView beginUpdates];
118 | [self.tableView reloadRowsAtIndexPaths:@[ indexPath ]
119 | withRowAnimation:UITableViewRowAnimationNone];
120 | [self.tableView endUpdates];
121 | }
122 | }
123 |
124 | - (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer
125 | didFinishSpeechUtterance:(AVSpeechUtterance *)utterance {
126 | NSIndexPath *indexPath = [_speakingCellIndexes firstObject];
127 | if (indexPath) {
128 | [_speakingCellIndexes removeObjectAtIndex:0];
129 |
130 | // Set speech icon back to normal when the country's name is finished being spoken
131 | if ([self.tableView.indexPathsForVisibleRows containsObject:indexPath]) {
132 | CountryCell *cell =
133 | (CountryCell *)[self tableView:self.tableView cellForRowAtIndexPath:indexPath];
134 | cell.speakingName = NO;
135 |
136 | [self.tableView beginUpdates];
137 | [self.tableView reloadRowsAtIndexPaths:@[ indexPath ]
138 | withRowAnimation:UITableViewRowAnimationNone];
139 | [self.tableView endUpdates];
140 | }
141 | }
142 | }
143 |
144 | - (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer
145 | didCancelSpeechUtterance:(AVSpeechUtterance *)utterance {
146 | // If the version of iOS is too old (~8.1 or earlier), we may be unable to speak country names.
147 | // In that case, present an alert to the user.
148 | NSIndexPath *indexPath = [_speakingCellIndexes firstObject];
149 | if (indexPath) {
150 | [_speakingCellIndexes removeObjectAtIndex:0];
151 | }
152 |
153 | static dispatch_once_t onceToken;
154 | dispatch_once(&onceToken, ^{
155 | NSString *alertTitle =
156 | NSLocalizedString(@"Speech Error", @"Speech Error Alert Title");
157 | NSString *alertMessage =
158 | NSLocalizedString(@"Unable to speak country names", @"Speech Error Alert Message");
159 | UIAlertController *alertController =
160 | [UIAlertController alertControllerWithTitle:alertTitle
161 | message:alertMessage
162 | preferredStyle:UIAlertControllerStyleAlert];
163 | NSString *actionTitle = NSLocalizedString(@"Dismiss", @"Speech Error Alert Dismiss");
164 | UIAlertAction *dismissAction =
165 | [UIAlertAction actionWithTitle:actionTitle
166 | style:UIAlertActionStyleCancel
167 | handler:^(UIAlertAction * _Nonnull action) {
168 | [self dismissViewControllerAnimated:YES completion:nil];
169 | }];
170 | [alertController addAction:dismissAction];
171 |
172 | [self presentViewController:alertController animated:YES completion:nil];
173 | });
174 | }
175 |
176 | @end
177 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/ARG.imageset/ARG.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/ARG.imageset/ARG.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/ARG.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "ARG.png",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/AUS.imageset/AUS.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/AUS.imageset/AUS.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/AUS.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "AUS.png",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/BTN.imageset/BTN.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/BTN.imageset/BTN.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/BTN.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "BTN.png",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/CAN.imageset/CAN.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/CAN.imageset/CAN.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/CAN.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "CAN.png",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/FRA.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "FRA.png",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/FRA.imageset/FRA.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/FRA.imageset/FRA.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/GRC.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "GRC.png",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/GRC.imageset/GRC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/GRC.imageset/GRC.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/IND.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IND.png",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/IND.imageset/IND.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/IND.imageset/IND.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/JAM.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "JAM.png",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/JAM.imageset/JAM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/JAM.imageset/JAM.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/JPN.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "JPN.png",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/JPN.imageset/JPN.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/JPN.imageset/JPN.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/MEX.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "MEX.png",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/MEX.imageset/MEX.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/MEX.imageset/MEX.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/NPL.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "NPL.png",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/NPL.imageset/NPL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/NPL.imageset/NPL.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/PNG.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "PNG.png",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/PNG.imageset/PNG.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/PNG.imageset/PNG.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/QAT.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "QAT.png",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/QAT.imageset/QAT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/QAT.imageset/QAT.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/SVK.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "SVK.png",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/SVK.imageset/SVK.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/SVK.imageset/SVK.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/TUN.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "TUN.png",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/TUN.imageset/TUN.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/TUN.imageset/TUN.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/USA.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "USA.png",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/USA.imageset/USA.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/USA.imageset/USA.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/ZAF.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "ZAF.png",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/ZAF.imageset/ZAF.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/ZAF.imageset/ZAF.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/ZMB.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "ZMB.png",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/ZMB.imageset/ZMB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/material-foundation/material-internationalization-ios/305aa8d276f5137c98c5c1c888efc22e02251ee7/Examples/Flags/MDFInternationalizationExample/Flags.xcassets/ZMB.imageset/ZMB.png
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | Flags
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | LSRequiresIPhoneOS
26 |
27 | UILaunchStoryboardName
28 | LaunchScreen
29 | UIMainStoryboardFile
30 | Main
31 | UIRequiredDeviceCapabilities
32 |
33 | armv7
34 |
35 | UISupportedInterfaceOrientations
36 |
37 | UIInterfaceOrientationPortrait
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/InformationViewController.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016-present Google Inc. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import
18 |
19 | @interface InformationViewController : UIViewController
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/InformationViewController.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016-present Google Inc. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import "InformationViewController.h"
18 |
19 | #import "MDFInternationalization.h"
20 |
21 | @interface InformationViewController ()
22 | @property (weak, nonatomic) IBOutlet UILabel *deviceLabel;
23 | @property (weak, nonatomic) IBOutlet UILabel *OSVersionLabel;
24 | @property (weak, nonatomic) IBOutlet UILabel *localeLabel;
25 | @property (weak, nonatomic) IBOutlet UILabel *LTRRTLLabel;
26 | @property (weak, nonatomic) IBOutlet UIImageView *originalImage;
27 | @property (weak, nonatomic) IBOutlet UIImageView *flippedImage;
28 | @property (weak, nonatomic) IBOutlet UIImageView *twiceFlippedImage;
29 | @property (weak, nonatomic) IBOutlet UIImageView *originalLTRImage;
30 | @property (weak, nonatomic) IBOutlet UIImageView *flippedLTRImage;
31 | @property (weak, nonatomic) IBOutlet UIImageView *twiceFlippedLTRImage;
32 | @property (weak, nonatomic) IBOutlet UIImageView *originalRTLImage;
33 | @property (weak, nonatomic) IBOutlet UIImageView *flippedRTLImage;
34 | @property (weak, nonatomic) IBOutlet UIImageView *twiceFlippedRTLImage;
35 |
36 | @end
37 |
38 | static NSString *sWikipediaURL = @"https://wikipedia.org";
39 |
40 | @implementation InformationViewController
41 |
42 | - (void)viewDidLoad {
43 | [super viewDidLoad];
44 | // Do any additional setup after loading the view.
45 |
46 | self.deviceLabel.text = [UIDevice currentDevice].name;
47 | NSString *versionString = [NSString stringWithFormat:@"%@ - %@ %@",
48 | [UIDevice currentDevice].localizedModel,
49 | [UIDevice currentDevice].systemName,
50 | [UIDevice currentDevice].systemVersion];
51 | self.OSVersionLabel.text = versionString;
52 | NSString *localeIdentifier = [NSLocale currentLocale].localeIdentifier;
53 | NSString *displayLocaleName =
54 | [[NSLocale currentLocale] displayNameForKey:NSLocaleIdentifier value:localeIdentifier];
55 | NSString *localeString;
56 | if (displayLocaleName) {
57 | localeString = [NSString stringWithFormat:@"%@ - %@", localeIdentifier, displayLocaleName];
58 | } else {
59 | localeString = localeIdentifier;
60 | }
61 |
62 | self.localeLabel.text = localeString;
63 | NSString *userInterfaceLayoutDirectionString;
64 | if ([UIApplication sharedApplication].userInterfaceLayoutDirection
65 | == UIUserInterfaceLayoutDirectionLeftToRight) {
66 | userInterfaceLayoutDirectionString = NSLocalizedString(@"LeftToRight", @"LeftToRight");
67 | } else {
68 | userInterfaceLayoutDirectionString = NSLocalizedString(@"RightToLeft", @"RightToLeft");
69 | }
70 | self.LTRRTLLabel.text = userInterfaceLayoutDirectionString;
71 |
72 | UIImage *standardImage = [UIImage imageNamed:@"Standard"];
73 | UIImage *flippedImage = [standardImage mdf_imageWithHorizontallyFlippedOrientation];
74 | UIImage *twiceFlippedImage = [flippedImage mdf_imageWithHorizontallyFlippedOrientation];
75 |
76 | self.originalImage.image = standardImage;
77 | self.originalLTRImage.image = standardImage;
78 | self.originalRTLImage.image = standardImage;
79 |
80 | self.flippedImage.image = flippedImage;
81 | self.flippedLTRImage.image = flippedImage;
82 | self.flippedRTLImage.image = flippedImage;
83 |
84 | self.twiceFlippedImage.image = twiceFlippedImage;
85 | self.twiceFlippedLTRImage.image = twiceFlippedImage;
86 | self.twiceFlippedRTLImage.image = twiceFlippedImage;
87 | }
88 |
89 | - (IBAction)navigateToWikipedia:(id)sender {
90 | if ([sender isKindOfClass:[UIButton class]]) {
91 | NSURL *wikipediaURL = [NSURL URLWithString:sWikipediaURL];
92 | if (wikipediaURL &&
93 | [[UIApplication sharedApplication] canOpenURL:wikipediaURL]) {
94 | [[UIApplication sharedApplication] openURL:wikipediaURL];
95 | }
96 | }
97 | }
98 |
99 | @end
100 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/ar.lproj/Countries.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Countries.strings
3 | MDFInternationalizationExample
4 |
5 | Created by Ian Gordon on 9/8/16.
6 | Copyright © 2016 Google. All rights reserved.
7 | */
8 |
9 | "ARG" = "الأرجنتين";
10 | "AUS" = "استراليا";
11 | "BTN" = "بوتان";
12 | "CAN" = "كندا";
13 | "FRA" = "فرنسا";
14 | "GRC" = "اليونان";
15 | "IND" = "الهند";
16 | "JAM" = "جامايكا";
17 | "JPN" = "اليابان";
18 | "MEX" = "المكسيك";
19 | "NPL" = "نيبال";
20 | "PNG" = "بابوا غينيا الجديدة";
21 | "QAT" = "قطر";
22 | "SVK" = "سلوفاكيا";
23 | "TUN" = "تونس";
24 | "USA" = "الولايات المتحدة الأمريكية";
25 | "ZAF" = "جنوب أفريقيا";
26 | "ZMB" = "زامبيا";
27 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/ar.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /*
2 | InfoPlist.strings
3 | MDFInternationalizationExample
4 |
5 | Created by Ian Gordon on 9/29/16.
6 | Copyright © 2016 Google. All rights reserved.
7 | */
8 |
9 | "CFBundleDisplayName" = "راية";
10 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/ar.lproj/Main.strings:
--------------------------------------------------------------------------------
1 |
2 | /* Class = "UILabel"; text = "Attributions"; ObjectID = "mgn-k3-F8V"; */
3 | "mgn-k3-F8V.text" = "عزو";
4 |
5 | /* Class = "UILabel"; text = "Flag images generated from SVG files available on wikipedia.org."; ObjectID = "1en-8q-12w"; */
6 | "1en-8q-12w.text" = "صور العلم ولدت من ملفات SVG المتاحة على wikipedia.org.";
7 |
8 | /* Class = "UIButton"; title = "en.wikipedia.org/wiki/Flag"; ObjectID = "ZNn-wx-pVo"; */
9 | "ZNn-wx-pVo.normalTitle" = "wikipedia.org";
10 |
11 | /* Class = "UILabel"; text = "Image Grid"; ObjectID = "XZB-gP-iGc"; */
12 | "XZB-gP-iGc.text" = "صورة الشبكة";
13 |
14 | /* Class = "UILabel"; text = "Device Information"; ObjectID = "YG5-ap-qm5"; */
15 | "YG5-ap-qm5.text" = "معلومات الجهاز";
16 |
17 | /* Class = "UITabBarItem"; title = "Flags"; ObjectID = "Gq3-Hs-m0C"; */
18 | "Gq3-Hs-m0C.title" = "راي";
19 |
20 | /* Class = "UILabel"; text = "Country Name"; ObjectID = "Jbo-SH-SeQ"; */
21 | "Jbo-SH-SeQ.text" = "Country Name";
22 |
23 | /* Class = "UITableViewController"; title = "Flags"; ObjectID = "M9q-Kw-lR5"; */
24 | "M9q-Kw-lR5.title" = "راية";
25 |
26 | /* Class = "UILabel"; text = "OS Version"; ObjectID = "PgA-Ot-YFF"; */
27 | "PgA-Ot-YFF.text" = "OS Version";
28 |
29 | /* Class = "UILabel"; text = "Locale"; ObjectID = "Smi-n9-SyQ"; */
30 | "Smi-n9-SyQ.text" = "Locale";
31 |
32 | /* Class = "UILabel"; text = "Device"; ObjectID = "mzM-ln-glZ"; */
33 | "mzM-ln-glZ.text" = "Device";
34 |
35 | /* Class = "UITabBarItem"; title = "Info"; ObjectID = "rz9-iM-jLd"; */
36 | "rz9-iM-jLd.title" = "معلومات";
37 |
38 | /* Class = "UILabel"; text = "LTR | RTL"; ObjectID = "spj-nM-7Zl"; */
39 | "spj-nM-7Zl.text" = "LTR | RTL";
40 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/en.lproj/Countries.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Countries.strings
3 | MDFInternationalizationExample
4 |
5 | Created by Ian Gordon on 9/8/16.
6 | Copyright © 2016 Google. All rights reserved.
7 | */
8 |
9 | "ARG" = "Argentina";
10 | "AUS" = "Australia";
11 | "BTN" = "Bhutan";
12 | "CAN" = "Canada";
13 | "FRA" = "France";
14 | "GRC" = "Greece";
15 | "IND" = "India";
16 | "JAM" = "Jamaica";
17 | "JPN" = "Japan";
18 | "MEX" = "Mexico";
19 | "NPL" = "Nepal";
20 | "PNG" = "Papua New Guinea";
21 | "QAT" = "Qatar";
22 | "SVK" = "Slovakia";
23 | "TUN" = "Tunisia";
24 | "USA" = "United States of America";
25 | "ZAF" = "South Africa";
26 | "ZMB" = "Zambia";
27 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/en.lproj/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | Flags
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | LSRequiresIPhoneOS
26 |
27 | UILaunchStoryboardName
28 | LaunchScreen
29 | UIMainStoryboardFile
30 | Main
31 | UIRequiredDeviceCapabilities
32 |
33 | armv7
34 |
35 | UISupportedInterfaceOrientations
36 |
37 | UIInterfaceOrientationPortrait
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /*
2 | InfoPlist.strings
3 | MDFInternationalizationExample
4 |
5 | Created by Ian Gordon on 9/29/16.
6 | Copyright © 2016 Google. All rights reserved.
7 | */
8 |
9 | "CFBundleDisplayName" = "Flags";
10 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/en.lproj/Main.strings:
--------------------------------------------------------------------------------
1 | /* Class = "UILabel"; text = "Attributions"; ObjectID = "mgn-k3-F8V"; */
2 | "mgn-k3-F8V.text" = "Attributions";
3 |
4 | /* Class = "UILabel"; text = "Flag images generated from SVG files available on wikipedia.org."; ObjectID = "1en-8q-12w"; */
5 | "1en-8q-12w.text" = "Flag images generated from SVG files available on wikipedia.org.";
6 |
7 | /* Class = "UIButton"; title = "en.wikipedia.org/wiki/Flag"; ObjectID = "ZNn-wx-pVo"; */
8 | "ZNn-wx-pVo.normalTitle" = "wikipedia.org";
9 |
10 | /* Class = "UILabel"; text = "Image Grid"; ObjectID = "XZB-gP-iGc"; */
11 | "XZB-gP-iGc.text" = "Image Grid";
12 |
13 | /* Class = "UILabel"; text = "Device Information"; ObjectID = "YG5-ap-qm5"; */
14 | "YG5-ap-qm5.text" = "Device Information";
15 |
16 | /* Class = "UITabBarItem"; title = "Flags"; ObjectID = "Gq3-Hs-m0C"; */
17 | "Gq3-Hs-m0C.title" = "Flags";
18 |
19 | /* Class = "UILabel"; text = "Country Name"; ObjectID = "Jbo-SH-SeQ"; */
20 | "Jbo-SH-SeQ.text" = "Country Name";
21 |
22 | /* Class = "UITableViewController"; title = "Flags"; ObjectID = "M9q-Kw-lR5"; */
23 | "M9q-Kw-lR5.title" = "Flags";
24 |
25 | /* Class = "UILabel"; text = "OS Version"; ObjectID = "PgA-Ot-YFF"; */
26 | "PgA-Ot-YFF.text" = "OS Version";
27 |
28 | /* Class = "UILabel"; text = "Locale"; ObjectID = "Smi-n9-SyQ"; */
29 | "Smi-n9-SyQ.text" = "Locale";
30 |
31 | /* Class = "UILabel"; text = "Device"; ObjectID = "mzM-ln-glZ"; */
32 | "mzM-ln-glZ.text" = "Device";
33 |
34 | /* Class = "UITabBarItem"; title = "Info"; ObjectID = "rz9-iM-jLd"; */
35 | "rz9-iM-jLd.title" = "Info";
36 |
37 | /* Class = "UILabel"; text = "LTR | RTL"; ObjectID = "spj-nM-7Zl"; */
38 | "spj-nM-7Zl.text" = "LTR | RTL";
39 |
--------------------------------------------------------------------------------
/Examples/Flags/MDFInternationalizationExample/main.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import "AppDelegate.h"
3 |
4 | int main(int argc, char * argv[]) {
5 | @autoreleasepool {
6 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/MDFInternationalization.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = "MDFInternationalization"
3 | s.version = "3.0.0"
4 | s.authors = "The Material Foundation Authors"
5 | s.summary = "Internationalization tools."
6 | s.homepage = "https://github.com/material-foundation/material-internationalization-ios"
7 | s.license = "Apache License, Version 2.0"
8 | s.source = { :git => "https://github.com/material-foundation/material-internationalization-ios.git", :tag => "v#{s.version}" }
9 | s.platform = :ios, "11.0"
10 |
11 | s.requires_arc = true
12 | s.public_header_files = "Sources/*.h"
13 | s.source_files = "Sources/*.{h,m}"
14 | s.header_mappings_dir = "Sources"
15 | s.header_dir = "MDFInternationalization"
16 | end
17 |
--------------------------------------------------------------------------------
/MDFInternationalization.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/MDFInternationalization.xcodeproj/xcshareddata/xcschemes/MDFInternationalization.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
49 |
50 |
51 |
52 |
53 |
54 |
64 |
65 |
71 |
72 |
73 |
74 |
75 |
76 |
82 |
83 |
89 |
90 |
91 |
92 |
94 |
95 |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/MDFInternationalization.xcodeproj/xcshareddata/xcschemes/MDFInternationalizationTests.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
16 |
18 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
40 |
41 |
42 |
43 |
49 |
50 |
52 |
53 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/MDFInternationalization.xcodeproj/xcuserdata/iangordon.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | MDFInternationalization.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 | MDFInternationalization.xcscheme_^#shared#^_
13 |
14 | orderHint
15 | 0
16 |
17 | MDFInternationalizationTests.xcscheme
18 |
19 | orderHint
20 | 1
21 |
22 | MDFInternationalizationTests.xcscheme_^#shared#^_
23 |
24 | orderHint
25 | 1
26 |
27 |
28 | SuppressBuildableAutocreation
29 |
30 | 4096E5AE1D78CB5500389ECD
31 |
32 | primary
33 |
34 |
35 | 4096E5B81D78CB5500389ECD
36 |
37 | primary
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MDFInternationalization
2 |
3 | MDFInternationalization assists in internationalizing your iOS app or components' user interface.
4 |
5 | [](https://github.com/material-foundation/material-internationalization-ios/blob/develop/LICENSE)
6 | [](https://github.com/material-foundation/material-internationalization-ios/releases)
7 | [](https://travis-ci.org/material-foundation/material-internationalization-ios)
8 | [](https://img.shields.io/cocoapods/v/MDFInternationalization.svg)
9 | [](https://github.com/Carthage/Carthage)
10 |
11 | ## Right-to-Left calculations for CGRects and UIEdgeInsets
12 |
13 | A UIView is positioned within its superview in terms of a frame (CGRect) consisting of an
14 | origin and a size. When a device is set to a language that is written from Right-to-Left (RTL),
15 | we often want to mirror the interface around the vertical axis. This library contains
16 | functions to assist in modifying frames and edge insets for RTL.
17 |
18 | ``` obj-c
19 | // To flip a subview's frame horizontally, pass in subview.frame and the width of its parent.
20 | CGRect originalFrame = childView.frame;
21 | CGRect flippedFrame = MDFRectFlippedHorizontally(originalFrame, CGRectGetWidth(self.bounds));
22 | childView.frame = flippedFrame;
23 | ```
24 |
25 | ## Mirroring Images
26 |
27 | A category on UIImage backports iOS 10's `[UIImage imageWithHorizontallyFlippedOrientation]` to
28 | earlier versions of iOS.
29 |
30 | ``` obj-c
31 | // To mirror on image, invoke mdf_imageWithHorizontallyFlippedOrientation.
32 | UIImage *mirroredImage = [originalImage mdf_imageWithHorizontallyFlippedOrientation];
33 | ```
34 |
35 | ## Adding semantic context
36 |
37 | A category on UIView backports iOS 9's `-[UIView semanticContentAttribute]` and iOS 10's
38 | `-[UIView effectiveUserInterfaceLayoutDirection]` to earlier versions of iOS.
39 |
40 | ``` obj-c
41 | // To set a semantic content attribute, set the mdf_semanticContentAttribute property.
42 | lockedLTRView.mdf_semanticContentAttribute = UISemanticContentAttributeForceLeftToRight;
43 |
44 | // mdf_semanticContentAttribute is used to calculate the mdf_effectiveUserInterfaceLayoutDirection
45 | if (customView.mdf_effectiveUserInterfaceLayoutDirection == UIUserInterfaceLayoutDirectionRightToLeft) {
46 | // Update customView's layout to be in RTL mode.
47 | }
48 | ```
49 |
50 | ## Embedding Bi-directional strings
51 |
52 | A category on NSString offers a simple API to wrap strings in Unicode markers so that LTR
53 | and RTL text can co-exist in the same string.
54 |
55 | ``` obj-c
56 | // To embed an RTL string in an existing LTR string we should wrap it in Unicode directionality
57 | // markers to maintain preoper rendering.
58 |
59 | // The name of a restaurant is in Arabic (RTL), but the rest of string is in Latin (LTR).
60 | NSString *wrappedRestaurantName =
61 | [restaurantName mdf_stringWithStereoReset:NSLocaleLanguageDirectionRightToLeft
62 | context:NSLocaleLanguageDirectionLeftToRight];
63 |
64 | NSString *reservationString = [NSString stringWithFormat:@"%@ : %ld", wrappedRestaurantName, attendees];
65 | ```
66 |
67 | ## Usage
68 |
69 | See Examples/Flags for a detailed example of how to use the functionality provided by this library.
70 |
71 |
72 | ## License
73 |
74 | MDFInternationalization is licensed under the [Apache License Version 2.0](LICENSE).
75 |
--------------------------------------------------------------------------------
/Sources/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 3.0.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(CURRENT_PROJECT_VERSION)
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Sources/MDFInternationalization.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016-present Google Inc. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import
18 |
19 | #import "MDFRTL.h" // IWYU pragma: keep
20 | #import "NSLocale+MaterialRTL.h" // IWYU pragma: keep
21 | #import "NSString+MaterialBidi.h" // IWYU pragma: keep
22 | #import "UIImage+MaterialRTL.h" // IWYU pragma: keep
23 | #import "UIView+MaterialRTL.h" // IWYU pragma: keep
24 |
25 | //! Project version number for MDFInternationalization.
26 | FOUNDATION_EXPORT double MDFInternationalizationVersionNumber;
27 |
28 | //! Project version string for MDFInternationalization.
29 | FOUNDATION_EXPORT const unsigned char MDFInternationalizationVersionString[];
30 |
--------------------------------------------------------------------------------
/Sources/MDFRTL.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016-present Google Inc. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import
18 |
19 | /**
20 | Leading autoresizing mask based on layoutDirection. 'Leading' is 'Left' in
21 | UIUserInterfaceLayoutDirectionLeftToRight, 'Right' otherwise.
22 |
23 | @param layoutDirection The layout direction to consider when computing the autoresizing mask.
24 | @return The leading margin part of an autoresizing mask.
25 | */
26 | FOUNDATION_EXPORT UIViewAutoresizing MDFLeadingMarginAutoresizingMaskForLayoutDirection(
27 | UIUserInterfaceLayoutDirection layoutDirection);
28 |
29 | /**
30 | Trailing autoresizing masks based on layoutDirection. 'Trailing' is 'Right' in
31 | UIUserInterfaceLayoutDirectionLeftToRight, 'Left' otherwise.
32 |
33 | @param layoutDirection The layout direction to consider to compute the autoresizing mask.
34 | @return The trailing margin part of an autoresizing mask.
35 | */
36 | FOUNDATION_EXPORT UIViewAutoresizing MDFTrailingMarginAutoresizingMaskForLayoutDirection(
37 | UIUserInterfaceLayoutDirection layoutDirection);
38 |
39 | /**
40 | The frame to use when actually laying out a view in its superview.
41 |
42 | A view is conceptually positioned within its superview in terms of leading/trailing. When it's time
43 | to actually lay out (i.e. setting frames), you position the frame as you usually would, but if you
44 | are in the opposite layout direction you call this function to return a rect that has been flipped
45 | around the vertical axis.
46 |
47 | @note Example: Flipping the frame of a subview 50pts wide at 10pts from the leading edge of a
48 | bounding view.
49 |
50 | CGRect frame = CGRectMake(10, originY, 50, height);
51 | CGFloat containerWidth = CGRectGetWidth(self.bounds);
52 | if (layoutDirection == UIUserInterfaceLayoutDirectionRightToLeft) {
53 | frame = MDFRectFlippedHorizontally(frame, containerWidth);
54 | }
55 |
56 | In LTR, frame is { { 10, originY }, { 50, height } } in a 100 wide bounding view.
57 | +----------------------------------------100----------------------------------------+
58 | | |
59 | | 10 +--------------------50--------------------+ |
60 | | | | |
61 | | +------------------------------------------+ |
62 | | |
63 | +----------------------------------------100----------------------------------------+
64 |
65 | In RTL, frame is { { 40, originY }, { 50, height } }.
66 | +----------------------------------------100----------------------------------------+
67 | | |
68 | | 40 +--------------------50--------------------+ |
69 | | | | |
70 | | +------------------------------------------+ |
71 | | |
72 | +----------------------------------------100----------------------------------------+
73 |
74 | @param frame The frame to convert.
75 | @param containerWidth The superview's bounds's width.
76 | @return The frame mirrored around the vertical axis.
77 | */
78 | FOUNDATION_EXPORT CGRect MDFRectFlippedHorizontally(CGRect frame, CGFloat containerWidth);
79 |
80 |
81 | /**
82 | Creates a UIEdgeInsets instance with its left and right values exchanged.
83 |
84 | @param insets The insets we are intending to flip horizontally.
85 | @return Insets with the right and left values exchanged.
86 | */
87 | FOUNDATION_EXPORT UIEdgeInsets MDFInsetsFlippedHorizontally(UIEdgeInsets insets);
88 |
89 | /**
90 | Creates a UIEdgeInsets instance from the parameters while obeying layoutDirection.
91 |
92 | If layoutDirection is UIUserInterfaceLayoutDirectionLeftToRight, then the left inset is leading and
93 | the right inset is trailing, otherwise they are reversed.
94 |
95 | @param top The top inset.
96 | @param leading The leading inset.
97 | @param bottom The bottom inset.
98 | @param trailing The trailing inset.
99 | @return Insets in terms of left/right, already internationalized based on the layout direction.
100 | */
101 | FOUNDATION_EXPORT UIEdgeInsets MDFInsetsMakeWithLayoutDirection(CGFloat top,
102 | CGFloat leading,
103 | CGFloat bottom,
104 | CGFloat trailing,
105 | UIUserInterfaceLayoutDirection layoutDirection);
106 |
--------------------------------------------------------------------------------
/Sources/MDFRTL.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016-present Google Inc. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import "MDFRTL.h"
18 |
19 | UIViewAutoresizing MDFLeadingMarginAutoresizingMaskForLayoutDirection(
20 | UIUserInterfaceLayoutDirection layoutDirection) {
21 | switch (layoutDirection) {
22 | case UIUserInterfaceLayoutDirectionLeftToRight:
23 | return UIViewAutoresizingFlexibleLeftMargin;
24 | case UIUserInterfaceLayoutDirectionRightToLeft:
25 | return UIViewAutoresizingFlexibleRightMargin;
26 | }
27 | NSCAssert(NO, @"Invalid enumeration value %i.", (int)layoutDirection);
28 | return UIViewAutoresizingFlexibleLeftMargin;
29 | }
30 |
31 | UIViewAutoresizing MDFTrailingMarginAutoresizingMaskForLayoutDirection(
32 | UIUserInterfaceLayoutDirection layoutDirection) {
33 | switch (layoutDirection) {
34 | case UIUserInterfaceLayoutDirectionLeftToRight:
35 | return UIViewAutoresizingFlexibleRightMargin;
36 | case UIUserInterfaceLayoutDirectionRightToLeft:
37 | return UIViewAutoresizingFlexibleLeftMargin;
38 | }
39 | NSCAssert(NO, @"Invalid enumeration value %i.", (int)layoutDirection);
40 | return UIViewAutoresizingFlexibleRightMargin;
41 | }
42 |
43 | CGRect MDFRectFlippedHorizontally(CGRect frame, CGFloat containerWidth) {
44 | CGRect flippedRect = CGRectStandardize(frame);
45 | CGFloat leadingInset = CGRectGetMinX(flippedRect);
46 | CGFloat width = CGRectGetWidth(flippedRect);
47 | flippedRect.origin.x = containerWidth - leadingInset - width;
48 |
49 | return flippedRect;
50 | }
51 |
52 | UIEdgeInsets MDFInsetsFlippedHorizontally(UIEdgeInsets insets) {
53 | UIEdgeInsets flippedInsets = insets;
54 | flippedInsets.left = insets.right;
55 | flippedInsets.right = insets.left;
56 |
57 | return flippedInsets;
58 | }
59 |
60 | UIEdgeInsets MDFInsetsMakeWithLayoutDirection(CGFloat top,
61 | CGFloat leading,
62 | CGFloat bottom,
63 | CGFloat trailing,
64 | UIUserInterfaceLayoutDirection layoutDirection) {
65 | switch (layoutDirection) {
66 | case UIUserInterfaceLayoutDirectionLeftToRight:
67 | return UIEdgeInsetsMake(top, leading, bottom, trailing);
68 | case UIUserInterfaceLayoutDirectionRightToLeft:
69 | return UIEdgeInsetsMake(top, trailing, bottom, leading);
70 | }
71 | NSCAssert(NO, @"Invalid enumeration value %i.", (int)layoutDirection);
72 | return UIEdgeInsetsMake(top, leading, bottom, trailing);
73 | }
74 |
--------------------------------------------------------------------------------
/Sources/NSLocale+MaterialRTL.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2018-present Google Inc. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import
18 |
19 | @interface NSLocale (MaterialRTL)
20 |
21 | /**
22 | Is the direction of the current locale's default language Left-To-Right?
23 |
24 | @return YES if the language is LTR, NO if the language is any other direction.
25 | */
26 | + (BOOL)mdf_isDefaultLanguageLTR;
27 |
28 | /**
29 | Is the direction of the current locale's default language Right-To-Left?
30 |
31 | @return YES if the language is RTL, NO if the language is any other direction.
32 | */
33 | + (BOOL)mdf_isDefaultLanguageRTL;
34 |
35 | @end
36 |
37 |
--------------------------------------------------------------------------------
/Sources/NSLocale+MaterialRTL.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2018-present Google Inc. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import "NSLocale+MaterialRTL.h"
18 |
19 | @implementation NSLocale (MaterialRTL)
20 |
21 | + (BOOL)mdf_isDefaultLanguageLTR {
22 | NSString *languageCode = [[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode];
23 | NSLocaleLanguageDirection characterDirection =
24 | [NSLocale characterDirectionForLanguage:languageCode];
25 | BOOL localeLanguageDirectionIsLTR = (characterDirection == NSLocaleLanguageDirectionLeftToRight);
26 | return localeLanguageDirectionIsLTR;
27 | }
28 |
29 | + (BOOL)mdf_isDefaultLanguageRTL {
30 | NSString *languageCode = [[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode];
31 | NSLocaleLanguageDirection characterDirection =
32 | [NSLocale characterDirectionForLanguage:languageCode];
33 | BOOL localeLanguageDirectionIsRTL = (characterDirection == NSLocaleLanguageDirectionRightToLeft);
34 | return localeLanguageDirectionIsRTL;
35 | }
36 |
37 | @end
38 |
39 |
--------------------------------------------------------------------------------
/Sources/NSString+MaterialBidi.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2018-present Google Inc. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import
18 |
19 | @interface NSString (MaterialBidi)
20 |
21 | /**
22 | Uses CFStringTokenizerCopyBestStringLanguage to determine string's language direction.
23 | If the language direction is unknown or vertical returns left-to-right.
24 |
25 | As CFStringTokenizerCopyBestStringLanguage is Apple's API, its result may change if
26 | Apple improves or modifies the implementation.
27 |
28 | @return the direction of the string
29 | */
30 | - (NSLocaleLanguageDirection)mdf_calculatedLanguageDirection;
31 |
32 | /**
33 | Initializes a copy of the string tagged with the given language direction. This
34 | formatting adds the appropriate Unicode embedding characters at the beginning and end of the
35 | string.
36 |
37 | Only NSLocaleLanguageDirectionLeftToRight and NSLocaleLanguageDirectionRightToLeft
38 | language directions are supported. Other values of NSLocalLanguageDirection will
39 | return a copy of self.
40 |
41 | Returns a string wrapped with Unicode bidi formatting characters by inserting these characters
42 | around the string:
43 | RLE+|string|+PDF for RTL text, or LRE+|string|+PDF for LTR text.
44 |
45 | @returns the new string.
46 | */
47 | - (nonnull NSString *)mdf_stringWithBidiEmbedding:(NSLocaleLanguageDirection)languageDirection;
48 |
49 | /**
50 | Returns a copy of the string explicitly tagged with a language direction.
51 |
52 | Uses mdf_calculatedLanguageDirection to determine string's language direction then invokes
53 | mdf_stringWithBidiEmbedding:.
54 |
55 | @return the new string.
56 | */
57 | - (nonnull NSString *)mdf_stringWithBidiEmbedding;
58 |
59 | /**
60 | This method will wrap the string in embedding (LRE/RLE and PDF) characters, based on the string
61 | direction and additionally wrapping the string in marks (LRM and RLM) if the string's direction
62 | is different from the context direction.
63 |
64 | |direction| can be NSLocaleLanguageDirectionLeftToRight, NSLocaleLanguageDirectionRightToLeft, or
65 | NSLocaleLanguageDirectionUnknown. If NSLocaleLanguageDirectionUnknown, the direction of the string
66 | will be calculated with mdf_calculatedLanguageDirection.
67 |
68 | |contextDirection| must be specified and cannot be unknown. Only
69 | NSLocaleLanguageDirectionLeftToRight and NSLocaleLanguageDirectionRightToLeft language directions
70 | are supported.
71 |
72 | @returns the new string.
73 | */
74 | - (nonnull NSString *)mdf_stringWithStereoReset:(NSLocaleLanguageDirection)direction
75 | context:(NSLocaleLanguageDirection)contextDirection;
76 |
77 | /**
78 | Returns a new string in which all occurrences of Unicode bidirectional format markers are removed.
79 |
80 | @returns the new string.
81 | */
82 | - (nonnull NSString *)mdf_stringWithBidiMarkersStripped;
83 |
84 | @end
85 |
--------------------------------------------------------------------------------
/Sources/NSString+MaterialBidi.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2018-present Google Inc. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import "NSString+MaterialBidi.h"
18 |
19 | #import
20 |
21 | @implementation NSString (MaterialBidi)
22 |
23 | // https://www.w3.org/International/questions/qa-bidi-unicode-controls
24 | //TODO: Reach out to AAA about the utility of the Isolate markers
25 | // ??? Do we want Embedding or Isolate markers? w3 recommends isolate?
26 | // Add reference : Unicode® Standard Annex #9 UNICODE BIDIRECTIONAL ALGORITHM
27 | // go/android-bidiformatter
28 | // http://unicode.org/reports/tr9/
29 |
30 | // Mark influences the directionality of neutral characters when the context is opposite of the
31 | // neutral chatacter's desired directionality.
32 | static NSString *kMDFLTRMark = @"\u200e"; // left-to-right mark
33 | static NSString *kMDFRTLMark = @"\u200f"; // right-to-left mark
34 |
35 | // Embedding indicates a text segment is embedded in a larger context with the opposite
36 | // directionality.
37 | static NSString *kMDFLTREmbedding = @"\u202a"; // left-to-right embedding
38 | static NSString *kMDFRTLEmbedding = @"\u202b"; // right-to-left embedding
39 |
40 | // Override reverses the directionality of strongly LTR or RTL characters
41 | static NSString *kMDFLTROverride = @"\u202d"; // left-to-right override
42 | static NSString *kMDFRTLOverride = @"\u202e"; // right-to-left override
43 |
44 | // Pop is used to denote the end of an embedding or override text segment
45 | static NSString *kMDFPopFormatting = @"\u202c"; // pop directional formatting
46 |
47 | // Version 6.3.0 Bidi algorithm additions
48 | // The following only work on iOS 10+
49 |
50 | // Isolate indicates that the text segment has an internal directionality with no effect on
51 | // surrounding characters.
52 | static NSString *kMDFLTRIsolate = @"\u2066"; // left-to-right isolate
53 | static NSString *kMDFRTLIsolate = @"\u2067"; // right-to-left isolate
54 | static NSString *kMDFFirstStrongIsolate = @"\u2068"; // first strong isolate
55 |
56 | // Pop Isolate is used to denote the end of an isolate text segment
57 | static NSString *kMDFPopIsolate = @"\u2069"; // pop directional isolate
58 |
59 |
60 | - (NSLocaleLanguageDirection)mdf_calculatedLanguageDirection {
61 | // Attempt to determine language of string.
62 | NSLocaleLanguageDirection languageDirection = NSLocaleLanguageDirectionUnknown;
63 |
64 | // Pass string into CoreFoundation's language identifier
65 | CFStringRef text = (__bridge CFStringRef)self;
66 | CFRange range = CFRangeMake(0, (CFIndex)[self length]);
67 | NSString *languageCode =
68 | (NSString *)CFBridgingRelease(CFStringTokenizerCopyBestStringLanguage(text, range));
69 | if (languageCode) {
70 | // If we identified a language, explicitly set the string direction based on that
71 | languageDirection = [NSLocale characterDirectionForLanguage:languageCode];
72 | }
73 |
74 | // If the result is not LTR or RTL, fallback to LTR
75 | // ??? Should I be defaulting to NSLocale.NSLocaleLanguageCode.characterDiretion?
76 | if (languageDirection != NSLocaleLanguageDirectionLeftToRight &&
77 | languageDirection != NSLocaleLanguageDirectionRightToLeft) {
78 | languageDirection = NSLocaleLanguageDirectionLeftToRight;
79 | }
80 |
81 | return languageDirection;
82 | }
83 |
84 | - (NSString *)mdf_stringWithBidiEmbedding {
85 | NSLocaleLanguageDirection languageDirection = [self mdf_calculatedLanguageDirection];
86 |
87 | return [self mdf_stringWithBidiEmbedding:languageDirection];
88 | }
89 |
90 | - (NSString *)mdf_stringWithBidiEmbedding:(NSLocaleLanguageDirection)languageDirection {
91 | if (languageDirection == NSLocaleLanguageDirectionRightToLeft) {
92 | return [NSString stringWithFormat:@"%@%@%@", kMDFRTLEmbedding, self, kMDFPopFormatting];
93 | } else if (languageDirection == NSLocaleLanguageDirectionLeftToRight) {
94 | return [NSString stringWithFormat:@"%@%@%@", kMDFLTREmbedding, self, kMDFPopFormatting];
95 | } else {
96 | // Return a copy original string if an unsupported direction is passed in.
97 | return [self copy];
98 | }
99 | }
100 |
101 | - (nonnull NSString *)mdf_stringWithStereoReset:(NSLocaleLanguageDirection)direction
102 | context:(NSLocaleLanguageDirection)contextDirection {
103 | #if DEBUG
104 | // Disable in release, as a pre-caution in case not everyone defines NS_BLOCK_ASSERTION.
105 | NSCAssert((contextDirection != NSLocaleLanguageDirectionLeftToRight ||
106 | contextDirection != NSLocaleLanguageDirectionRightToLeft),
107 | @"contextStringDirection must be passed in and set to either"
108 | "NSLocaleLanguageDirectionLeftToRight or NSLocaleLanguageDirectionRightToLeft.");
109 |
110 | NSCAssert((direction != NSLocaleLanguageDirectionLeftToRight ||
111 | direction != NSLocaleLanguageDirectionRightToLeft ||
112 | direction != NSLocaleLanguageDirectionUnknown),
113 | @"stringToBeInsertedDirection must be set to either NSLocaleLanguageDirectionUnknown,"
114 | "NSLocaleLanguageDirectionLeftToRight, or NSLocaleLanguageDirectionRightToLeft.");
115 | #endif
116 |
117 | if (self.length == 0) {
118 | return [self copy];
119 | }
120 |
121 | if (direction != NSLocaleLanguageDirectionLeftToRight &&
122 | direction != NSLocaleLanguageDirectionRightToLeft) {
123 | direction = [self mdf_calculatedLanguageDirection];
124 | }
125 |
126 | NSString *bidiEmbeddedString = [self mdf_stringWithBidiEmbedding:direction];
127 |
128 | NSString *bidiResetString;
129 | if (direction != contextDirection) {
130 | if (contextDirection == NSLocaleLanguageDirectionRightToLeft) {
131 | bidiResetString =
132 | [NSString stringWithFormat:@"%@%@%@", kMDFRTLMark, bidiEmbeddedString, kMDFRTLMark];
133 | } else {
134 | bidiResetString =
135 | [NSString stringWithFormat:@"%@%@%@", kMDFLTRMark, bidiEmbeddedString, kMDFLTRMark];
136 | }
137 | } else {
138 | bidiResetString = bidiEmbeddedString;
139 | }
140 |
141 | return bidiResetString;
142 | }
143 |
144 | - (NSString *)mdf_stringWithBidiMarkersStripped {
145 | NSString *strippedString = self;
146 | NSArray *directionalMarkers = @[ kMDFLTRMark,
147 | kMDFRTLMark,
148 | kMDFRTLEmbedding,
149 | kMDFLTREmbedding,
150 | kMDFRTLOverride,
151 | kMDFLTROverride,
152 | kMDFPopFormatting,
153 | kMDFLTRIsolate,
154 | kMDFRTLIsolate,
155 | kMDFFirstStrongIsolate,
156 | kMDFPopIsolate
157 | ];
158 | for (NSString *markerString in directionalMarkers) {
159 | strippedString =
160 | [strippedString stringByReplacingOccurrencesOfString:markerString withString:@""];
161 | }
162 | return strippedString;
163 | }
164 |
165 | @end
166 |
--------------------------------------------------------------------------------
/Sources/UIImage+MaterialRTL.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016-present Google Inc. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import
18 |
19 | /**
20 | Backporting of iOS 10's [UIImage imageWithHorizontallyFlippedOrientation].
21 | */
22 |
23 | @interface UIImage (MaterialRTL)
24 |
25 | /**
26 | On iOS 10 and above, calls [UIImage imageWithHorizontallyFlippedOrientation].
27 | Otherwise manually flips the image and returns the result.
28 |
29 | @return A horizontally mirrored version of this image.
30 | */
31 | - (nonnull UIImage *)mdf_imageWithHorizontallyFlippedOrientation;
32 |
33 | @end
34 |
--------------------------------------------------------------------------------
/Sources/UIImage+MaterialRTL.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016-present Google Inc. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import "UIImage+MaterialRTL.h"
18 |
19 | #import
20 | #import
21 |
22 | /** Returns the horizontally flipped version of the given UIImageOrientation. */
23 | static UIImageOrientation MDFRTLMirroredOrientation(UIImageOrientation sourceOrientation) {
24 | switch (sourceOrientation) {
25 | case UIImageOrientationUp:
26 | return UIImageOrientationUpMirrored;
27 | case UIImageOrientationDown:
28 | return UIImageOrientationDownMirrored;
29 | case UIImageOrientationLeft:
30 | return UIImageOrientationLeftMirrored;
31 | case UIImageOrientationRight:
32 | return UIImageOrientationRightMirrored;
33 | case UIImageOrientationUpMirrored:
34 | return UIImageOrientationUp;
35 | case UIImageOrientationDownMirrored:
36 | return UIImageOrientationDown;
37 | case UIImageOrientationLeftMirrored:
38 | return UIImageOrientationLeft;
39 | case UIImageOrientationRightMirrored:
40 | return UIImageOrientationRight;
41 | }
42 | NSCAssert(NO, @"Invalid enumeration value %i.", (int)sourceOrientation);
43 | return UIImageOrientationUpMirrored;
44 | }
45 |
46 | /**
47 | Returns a copy of the image actually flipped. The orientation and scale are consumed, while the
48 | rendering mode is ported to the new image.
49 | */
50 | static UIImage *MDFRTLFlippedImage(UIImage *image) {
51 | CGSize size = image.size;
52 | CGRect rect = CGRectMake(0.0f, 0.0f, size.width, size.height);
53 |
54 | UIGraphicsBeginImageContextWithOptions(rect.size, NO, image.scale);
55 | CGContextRef context = UIGraphicsGetCurrentContext();
56 | CGContextSetShouldAntialias(context, true);
57 | CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
58 |
59 | // Note: UIKit's and CoreGraphics coordinates systems are flipped vertically (UIKit's Y axis goes
60 | // down, while CoreGraphics' goes up).
61 | switch (image.imageOrientation) {
62 | case UIImageOrientationUp:
63 | CGContextScaleCTM(context, -1, -1);
64 | CGContextTranslateCTM(context, -rect.size.width, -rect.size.height);
65 | break;
66 | case UIImageOrientationDown:
67 | // Orientation down is equivalent to a 180º rotation. The difference in coordinates systems is
68 | // thus sufficient and nothing needs to be down to flip the image.
69 | break;
70 | case UIImageOrientationLeft:
71 | CGContextRotateCTM(context, -(CGFloat)M_PI_2);
72 | CGContextTranslateCTM(context, -rect.size.width, 0);
73 | break;
74 | case UIImageOrientationRight:
75 | CGContextRotateCTM(context, (CGFloat)M_PI_2);
76 | CGContextTranslateCTM(context, 0, -rect.size.width);
77 | break;
78 | case UIImageOrientationUpMirrored:
79 | CGContextScaleCTM(context, 1, -1);
80 | CGContextTranslateCTM(context, 0, -rect.size.height);
81 | break;
82 | case UIImageOrientationDownMirrored:
83 | CGContextScaleCTM(context, -1, 1);
84 | CGContextTranslateCTM(context, -rect.size.width, 0);
85 | break;
86 | case UIImageOrientationLeftMirrored:
87 | CGContextRotateCTM(context, -(CGFloat)M_PI_2);
88 | CGContextTranslateCTM(context, -rect.size.width, 0);
89 | CGContextScaleCTM(context, -1, 1);
90 | CGContextTranslateCTM(context, -rect.size.width, 0);
91 | break;
92 | case UIImageOrientationRightMirrored:
93 | CGContextRotateCTM(context, (CGFloat)M_PI_2);
94 | CGContextTranslateCTM(context, 0, -rect.size.width);
95 | CGContextScaleCTM(context, -1, 1);
96 | CGContextTranslateCTM(context, -rect.size.width, 0);
97 | break;
98 | default:
99 | NSCAssert(NO, @"Invalid enumeration value %i.", (int)image.imageOrientation);
100 | }
101 |
102 | // If the UIImage is not backed by a CGImage, create one from the CIImage
103 | if (image.CGImage) {
104 | CGContextDrawImage(context, rect, image.CGImage);
105 | } else if (image.CIImage) {
106 | CIImage *coreImage = image.CIImage;
107 | CIContext *coreImageContext = [CIContext context];
108 | CGImageRef coreGraphicsImage =
109 | [coreImageContext createCGImage:coreImage fromRect:coreImage.extent];
110 | if (coreGraphicsImage) {
111 | CGContextDrawImage(context, rect, coreGraphicsImage);
112 | CFRelease(coreGraphicsImage);
113 | coreGraphicsImage = NULL;
114 | }
115 | } else {
116 | NSCAssert(NO, @"Unable to flip image without a CGImage or CIImage backing store");
117 | }
118 |
119 | UIImage *drawnImage = UIGraphicsGetImageFromCurrentImageContext();
120 | UIGraphicsEndImageContext();
121 |
122 | // Port the rendering mode.
123 | UIImage *flippedImage = [drawnImage imageWithRenderingMode:image.renderingMode];
124 | return flippedImage;
125 | }
126 |
127 | @implementation UIImage (MaterialRTL)
128 |
129 | - (UIImage *)mdf_imageWithHorizontallyFlippedOrientation {
130 | // On iOS 10 and above, UIImage supports the imageWithHorizontallyFlippedOrientation method.
131 | // Otherwise, we manually manipulate the image.
132 | if ([self respondsToSelector:@selector(imageWithHorizontallyFlippedOrientation)]) {
133 | //TODO: (#22) Replace with @availability when we adopt Xcode 9 as our minimum supported version.
134 | #pragma clang diagnostic push
135 | #pragma clang diagnostic ignored "-Wpartial-availability"
136 | return [self imageWithHorizontallyFlippedOrientation];
137 | #pragma clang diagnostic pop
138 | } else {
139 | UIImage *mirroredImage;
140 | UIImageOrientation mirroredOrientation = MDFRTLMirroredOrientation(self.imageOrientation);
141 | if (self.CGImage) {
142 | CGImageRef _Nonnull image = (CGImageRef _Nonnull)self.CGImage;
143 | mirroredImage = [[self class] imageWithCGImage:image
144 | scale:self.scale
145 | orientation:mirroredOrientation];
146 | } else if (self.CIImage) {
147 | CIImage * _Nonnull image = (CIImage * _Nonnull)self.CIImage;
148 | mirroredImage = [[self class] imageWithCIImage:image
149 | scale:self.scale
150 | orientation:mirroredOrientation];
151 | }
152 |
153 | // If we were unsuccessful, manually flip the image using a Core Graphics context
154 | if (!mirroredImage) {
155 | mirroredImage = MDFRTLFlippedImage(self);
156 | }
157 |
158 | // On iOS9- [UIImage imageWithCGImage:scale:orientation:] loses the rendering mode.
159 | // Restore it if the new renderingMode does not match the current renderingMode.
160 | if (mirroredImage.renderingMode != self.renderingMode) {
161 | mirroredImage = [mirroredImage imageWithRenderingMode:self.renderingMode];
162 | }
163 |
164 | return mirroredImage;
165 | }
166 | }
167 |
168 | @end
169 |
--------------------------------------------------------------------------------
/Sources/UIView+MaterialRTL.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016-present Google Inc. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import
18 |
19 | /**
20 | Complete backporting of iOS 9's `-[UIView semanticContentAttribute]` and
21 | `+[UIView userInterfaceLayoutDirectionForSemanticContentAttribute:]`, and iOS 10's
22 | `-[UIView effectiveUserInterfaceLayoutDirection]` and
23 | `+[UIView userInterfaceLayoutDirectionForSemanticContentAttribute:relativeToLayoutDirection:]`.
24 | */
25 |
26 |
27 |
28 | @interface UIView (MaterialRTL)
29 |
30 | // UISemanticContentAttribute was added in iOS SDK 9.0 but is available on devices running earlier
31 | // version of iOS. We ignore the partial-availability warning that gets thrown on our use of this
32 | // symbol.
33 | #pragma clang diagnostic push
34 | #pragma clang diagnostic ignored "-Wpartial-availability"
35 |
36 | /**
37 | Returns the layout direction implied by the provided semantic content attribute relative to the
38 | application-wide layout direction (as returned by
39 | UIApplication.sharedApplication.userInterfaceLayoutDirection). However, if it's being called from
40 | an iOS 8 extension, it will return left-to-right every time.
41 |
42 | @param semanticContentAttribute The semantic content attribute.
43 | @return The layout direction.
44 | */
45 | + (UIUserInterfaceLayoutDirection)mdf_userInterfaceLayoutDirectionForSemanticContentAttribute:
46 | (UISemanticContentAttribute)semanticContentAttribute;
47 |
48 | /**
49 | Returns the layout direction implied by the provided semantic content attribute relative to the
50 | provided layout direction. For example, when provided a layout direction of
51 | RightToLeft and a semantic content attribute of Playback, this method returns LeftToRight. Layout
52 | and drawing code can use this method to determine how to arrange elements, but might find it easier
53 | to query the container view's mdf_effectiveUserInterfaceLayoutDirection property instead.
54 |
55 | @param semanticContentAttribute The semantic content attribute.
56 | @param layoutDirection The layout direction to consider.
57 | @return The implied layout direction.
58 | */
59 | + (UIUserInterfaceLayoutDirection)
60 | mdf_userInterfaceLayoutDirectionForSemanticContentAttribute:
61 | (UISemanticContentAttribute)semanticContentAttribute
62 | relativeToLayoutDirection:
63 | (UIUserInterfaceLayoutDirection)layoutDirection;
64 |
65 | #pragma clang diagnostic pop
66 |
67 | @end
68 |
--------------------------------------------------------------------------------
/Sources/UIView+MaterialRTL.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016-present Google Inc. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import "UIView+MaterialRTL.h"
18 |
19 | #import
20 |
21 | #define MDF_BASE_SDK_EQUAL_OR_ABOVE(x) \
22 | (defined(__IPHONE_##x) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_##x))
23 |
24 | // UISemanticContentAttribute was added in iOS SDK 9.0 but is available on devices running earlier
25 | // version of iOS. We ignore the partial-availability warning that gets thrown on our use of this
26 | // symbol.
27 | #pragma clang diagnostic push
28 | #pragma clang diagnostic ignored "-Wpartial-availability"
29 |
30 | static inline UIUserInterfaceLayoutDirection
31 | MDFUserInterfaceLayoutDirectionForSemanticContentAttributeRelativeToLayoutDirection(
32 | UISemanticContentAttribute semanticContentAttribute,
33 | UIUserInterfaceLayoutDirection userInterfaceLayoutDirection) {
34 | switch (semanticContentAttribute) {
35 | case UISemanticContentAttributeUnspecified:
36 | return userInterfaceLayoutDirection;
37 | case UISemanticContentAttributePlayback:
38 | case UISemanticContentAttributeSpatial:
39 | case UISemanticContentAttributeForceLeftToRight:
40 | return UIUserInterfaceLayoutDirectionLeftToRight;
41 | case UISemanticContentAttributeForceRightToLeft:
42 | return UIUserInterfaceLayoutDirectionRightToLeft;
43 | }
44 | NSCAssert(NO, @"Invalid enumeration value %i.", (int)semanticContentAttribute);
45 | return userInterfaceLayoutDirection;
46 | }
47 |
48 | @interface UIView (MaterialRTLPrivate)
49 |
50 | // On iOS 9 and above, mdf_semanticContentAttribute is backed by UIKit's semanticContentAttribute.
51 | // On iOS 8 and below, mdf_semanticContentAttribute is backed by an associated object.
52 | @property(nonatomic, setter=mdf_setAssociatedSemanticContentAttribute:)
53 | UISemanticContentAttribute mdf_associatedSemanticContentAttribute;
54 |
55 | @end
56 |
57 | @implementation UIView (MaterialRTL)
58 |
59 | - (UISemanticContentAttribute)mdf_semanticContentAttribute {
60 | #if MDF_BASE_SDK_EQUAL_OR_ABOVE(9_0)
61 | if ([self respondsToSelector:@selector(semanticContentAttribute)]) {
62 | return self.semanticContentAttribute;
63 | } else
64 | #endif // MDF_BASE_SDK_EQUAL_OR_ABOVE(9_0)
65 | {
66 | return self.mdf_associatedSemanticContentAttribute;
67 | }
68 | }
69 |
70 | - (void)mdf_setSemanticContentAttribute:(UISemanticContentAttribute)semanticContentAttribute {
71 | #if MDF_BASE_SDK_EQUAL_OR_ABOVE(9_0)
72 | if ([self respondsToSelector:@selector(semanticContentAttribute)]) {
73 | self.semanticContentAttribute = semanticContentAttribute;
74 | } else
75 | #endif // MDF_BASE_SDK_EQUAL_OR_ABOVE(9_0)
76 | {
77 | self.mdf_associatedSemanticContentAttribute = semanticContentAttribute;
78 | }
79 |
80 | // Invalidate the layout.
81 | [self setNeedsLayout];
82 | }
83 |
84 | + (UIUserInterfaceLayoutDirection)mdf_userInterfaceLayoutDirectionForSemanticContentAttribute:
85 | (UISemanticContentAttribute)attribute {
86 | #if MDF_BASE_SDK_EQUAL_OR_ABOVE(9_0)
87 | if ([self
88 | respondsToSelector:@selector(userInterfaceLayoutDirectionForSemanticContentAttribute:)]) {
89 | return [self userInterfaceLayoutDirectionForSemanticContentAttribute:attribute];
90 | } else
91 | #endif // MDF_BASE_SDK_EQUAL_OR_ABOVE(9_0)
92 | {
93 | // If we are running in the context of an app, we query [UIApplication sharedApplication].
94 | // Otherwise use a default of Left-to-Right.
95 | UIUserInterfaceLayoutDirection applicationLayoutDirection =
96 | UIUserInterfaceLayoutDirectionLeftToRight;
97 | NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
98 | // Can I use kAppBundleIdentifier ?
99 | if ([bundlePath hasSuffix:@".app"]) {
100 | // We can't call sharedApplication directly or an error gets thrown for app extensions.
101 | UIApplication *application =
102 | [[UIApplication class] performSelector:@selector(sharedApplication)];
103 | applicationLayoutDirection = application.userInterfaceLayoutDirection;
104 | }
105 | return [self
106 | mdf_userInterfaceLayoutDirectionForSemanticContentAttribute:attribute
107 | relativeToLayoutDirection:applicationLayoutDirection];
108 | }
109 | }
110 |
111 | + (UIUserInterfaceLayoutDirection)
112 | mdf_userInterfaceLayoutDirectionForSemanticContentAttribute:
113 | (UISemanticContentAttribute)semanticContentAttribute
114 | relativeToLayoutDirection:
115 | (UIUserInterfaceLayoutDirection)layoutDirection {
116 | #if MDF_BASE_SDK_EQUAL_OR_ABOVE(10_0)
117 | if ([self
118 | respondsToSelector:@selector(userInterfaceLayoutDirectionForSemanticContentAttribute:
119 | relativeToLayoutDirection:)]) {
120 | return [self userInterfaceLayoutDirectionForSemanticContentAttribute:semanticContentAttribute
121 | relativeToLayoutDirection:layoutDirection];
122 | } else {
123 | return MDFUserInterfaceLayoutDirectionForSemanticContentAttributeRelativeToLayoutDirection(
124 | semanticContentAttribute, layoutDirection);
125 | }
126 | #else
127 | return MDFUserInterfaceLayoutDirectionForSemanticContentAttributeRelativeToLayoutDirection(
128 | semanticContentAttribute, layoutDirection);
129 | #endif // MDF_BASE_SDK_EQUAL_OR_ABOVE(10_0)
130 | }
131 |
132 | @end
133 |
134 | @implementation UIView (MaterialRTLPrivate)
135 |
136 | - (UISemanticContentAttribute)mdf_associatedSemanticContentAttribute {
137 | NSNumber *semanticContentAttributeNumber =
138 | objc_getAssociatedObject(self, @selector(mdf_semanticContentAttribute));
139 | if (semanticContentAttributeNumber != nil) {
140 | return [semanticContentAttributeNumber integerValue];
141 | }
142 | return UISemanticContentAttributeUnspecified;
143 | }
144 |
145 | - (void)mdf_setAssociatedSemanticContentAttribute:
146 | (UISemanticContentAttribute)semanticContentAttribute {
147 | objc_setAssociatedObject(self, @selector(mdf_semanticContentAttribute),
148 | @(semanticContentAttribute), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
149 | }
150 |
151 | @end
152 |
153 | #pragma clang diagnostic pop
154 |
--------------------------------------------------------------------------------
/Tests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Tests/MDFBidiTests.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2018-present Google Inc. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import
18 |
19 | #import "MDFInternationalization.h"
20 |
21 | @interface MDFBidiTests : XCTestCase
22 |
23 | @end
24 |
25 | @implementation MDFBidiTests
26 |
27 | - (void)setUp {
28 | [super setUp];
29 | // Put setup code here. This method is called before the invocation of each test method in the class.
30 | }
31 |
32 | - (void)tearDown {
33 | // Put teardown code here. This method is called after the invocation of each test method in the class.
34 | [super tearDown];
35 | }
36 |
37 | - (void)testUniqueLocaleDirectionality {
38 | BOOL isLTR = [NSLocale mdf_isDefaultLanguageLTR];
39 | BOOL isRTL = [NSLocale mdf_isDefaultLanguageRTL];
40 |
41 | XCTAssertTrue(isLTR != isRTL, @"Locale cannot be LTR and RTL at the same time");
42 | }
43 |
44 | - (void)testLTRStringDirection {
45 | NSString *testString = @"The quick brown fox jumps over the lazy dog.";
46 | NSLocaleLanguageDirection MDFResult = [testString mdf_calculatedLanguageDirection];
47 | XCTAssertEqual(MDFResult, NSLocaleLanguageDirectionLeftToRight);
48 | }
49 |
50 | - (void)testPersoArabicRTLStringDirection {
51 | NSString *testString = @"الثعلب البني السريع يقفز فوق الكلب الكسول";
52 | NSLocaleLanguageDirection MDFResult = [testString mdf_calculatedLanguageDirection];
53 | XCTAssertEqual(MDFResult, NSLocaleLanguageDirectionRightToLeft);
54 | }
55 |
56 | - (void)testHebrewRTLStringDirection {
57 | NSString *testString = @"12 ספרים";
58 | NSLocaleLanguageDirection MDFResult = [testString mdf_calculatedLanguageDirection];
59 | XCTAssertEqual(MDFResult, NSLocaleLanguageDirectionRightToLeft);
60 | }
61 |
62 | - (void)testAddLTRMarkers {
63 | NSString *testString = @"quick brown fox";
64 | NSString *wrappedString =
65 | [testString mdf_stringWithBidiEmbedding:NSLocaleLanguageDirectionLeftToRight];
66 | XCTAssertTrue([wrappedString isEqualToString:@"\u202aquick brown fox\u202c"]);
67 | }
68 |
69 | - (void)testAddRTLMarkers {
70 | NSString *testString = @"quick brown fox";
71 | NSString *wrappedString =
72 | [testString mdf_stringWithBidiEmbedding:NSLocaleLanguageDirectionRightToLeft];
73 | XCTAssertTrue([wrappedString isEqualToString:@"\u202bquick brown fox\u202c"]);
74 | }
75 |
76 | - (void)testAddCalculatedMarkers {
77 | NSString *testString = @"The quick brown fox jumps over the lazy dog.";
78 | NSString *wrappedString =
79 | [testString mdf_stringWithBidiEmbedding];
80 | XCTAssertTrue([wrappedString isEqualToString:@"\u202aThe quick brown fox jumps over the lazy dog.\u202c"]);
81 | }
82 |
83 | - (void)testStripMarkers {
84 | NSString *testString = @"\u202aThe quick brown fox jumps over the lazy dog.\u202c";
85 | NSString *strippedString = [testString mdf_stringWithBidiMarkersStripped];
86 | XCTAssertTrue([strippedString isEqualToString:@"The quick brown fox jumps over the lazy dog."]);
87 | }
88 |
89 | - (void)testLTRStereoIsolateLTR {
90 | NSString *testString = @"The quick brown fox jumps over the lazy dog.";
91 | NSLocaleLanguageDirection stringDirection = NSLocaleLanguageDirectionLeftToRight;
92 | NSLocaleLanguageDirection contextDirection = NSLocaleLanguageDirectionLeftToRight;
93 |
94 | NSString *wrappedString =
95 | [testString mdf_stringWithStereoReset:stringDirection
96 | context:contextDirection];
97 |
98 | // ??? Since the context is the same as the string, do we need the markers
99 | XCTAssertTrue([wrappedString isEqualToString:@"\u202aThe quick brown fox jumps over the lazy dog.\u202c"]);
100 | }
101 |
102 | - (void)testLTRStereoIsolateRTL {
103 | NSString *testString = @"The quick brown fox jumps over the lazy dog.";
104 | NSLocaleLanguageDirection stringDirection = NSLocaleLanguageDirectionLeftToRight;
105 | NSLocaleLanguageDirection contextDirection = NSLocaleLanguageDirectionRightToLeft;
106 |
107 | NSString *wrappedString =
108 | [testString mdf_stringWithStereoReset:stringDirection
109 | context:contextDirection];
110 |
111 | // !!! wrappedString is "\u202b\u202aThe quick brown fox jumps over the lazy dog.\u202c\u202c
112 | // ??? Since the context is the same as the string, do we need the markers
113 | XCTAssertTrue([wrappedString isEqualToString:@"\u200f\u202aThe quick brown fox jumps over the lazy dog.\u202c\u200f"]);
114 | }
115 |
116 | - (void)testRTLStereoIsolateRTL {
117 | NSString *testString = @"The quick brown fox jumps over the lazy dog.";
118 | NSLocaleLanguageDirection stringDirection = NSLocaleLanguageDirectionRightToLeft;
119 | NSLocaleLanguageDirection contextDirection = NSLocaleLanguageDirectionRightToLeft;
120 |
121 | NSString *wrappedString =
122 | [testString mdf_stringWithStereoReset:stringDirection
123 | context:contextDirection];
124 |
125 | // !!! wrappedString is "\u202b\u202aThe quick brown fox jumps over the lazy dog.\u202c\u202c
126 | // ??? Since the context is the same as the string, do we need the markers
127 | XCTAssertTrue([wrappedString isEqualToString:@"\u202bThe quick brown fox jumps over the lazy dog.\u202c"]);
128 | }
129 |
130 | // Simple Tests
131 |
132 | - (void)testSimpleLanguageDirectionOfPunctuationString {
133 | NSString *testString = @"@#%+=-^*";
134 |
135 | // Then
136 | XCTAssertEqual([testString mdf_calculatedLanguageDirection], NSLocaleLanguageDirectionLeftToRight);
137 | }
138 |
139 | - (void)testSimpleLanguageDirectionOfNumericString {
140 | NSString *testString = @"123";
141 |
142 | // Then
143 | XCTAssertEqual([testString mdf_calculatedLanguageDirection], NSLocaleLanguageDirectionLeftToRight);
144 | }
145 |
146 | - (void)testSimpleLanguageDirectionOfHebrewString {
147 | NSString *testString = @"!שלום";
148 |
149 | // Then
150 | XCTAssertEqual([testString mdf_calculatedLanguageDirection], NSLocaleLanguageDirectionRightToLeft);
151 | }
152 |
153 | - (void)testSimpleLanguageDirectionOfEnglishString {
154 | NSString *testString = @"Hello!";
155 |
156 | // Then
157 | XCTAssertEqual([testString mdf_calculatedLanguageDirection], NSLocaleLanguageDirectionLeftToRight);
158 | }
159 |
160 | - (void)testSimpleLanguageDirectionOfEmptyString {
161 | NSString *testString = @"";
162 |
163 | // Then
164 | XCTAssertEqual([testString mdf_calculatedLanguageDirection], NSLocaleLanguageDirectionLeftToRight);
165 | }
166 |
167 | @end
168 |
--------------------------------------------------------------------------------
/Tests/MDFInternationalizationTests.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016-present Google Inc. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import
18 |
19 | //FIXME: Remove this file if there are no tests
20 |
21 | @interface MDFInternationalizationTests : XCTestCase
22 |
23 | @end
24 |
25 | @implementation MDFInternationalizationTests
26 |
27 | - (void)setUp {
28 | [super setUp];
29 | // Put setup code here. This method is called before the invocation of each test method in the class.
30 | }
31 |
32 | - (void)tearDown {
33 | // Put teardown code here. This method is called after the invocation of each test method in the class.
34 | [super tearDown];
35 | }
36 |
37 | @end
38 |
--------------------------------------------------------------------------------
/Tests/MDFRTLTests.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016-present Google Inc. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import
18 |
19 | #import "MDFInternationalization.h"
20 |
21 | @interface RTLTests : XCTestCase
22 |
23 | @end
24 |
25 | @implementation RTLTests
26 |
27 | - (void)setUp {
28 | [super setUp];
29 | // Put setup code here. This method is called before the invocation of each test method in the class.
30 | }
31 |
32 | - (void)tearDown {
33 | // Put teardown code here. This method is called after the invocation of each test method in the class.
34 | [super tearDown];
35 | }
36 |
37 | - (void)testMDCRectHorizontallyFlipped {
38 | CGRect frame = CGRectMake(10.0, 20.0, 50.0, 30.0);
39 | CGRect flippedFrame = MDFRectFlippedHorizontally(frame, 100.0);
40 | CGRect validResultFrame = CGRectMake(40.0, 20.0, 50.0, 30.0);
41 |
42 | XCTAssert(CGRectEqualToRect(flippedFrame, validResultFrame));
43 | }
44 |
45 | - (void)testMDCRectDoublyHorizontallyFlipped {
46 | CGRect frame = CGRectMake(10.0, 20.0, 50.0, 30.0);
47 | CGRect flippedFrame = MDFRectFlippedHorizontally(frame, 100.0);
48 | CGRect twiceFlippedFrame = MDFRectFlippedHorizontally(flippedFrame, 100.0);
49 |
50 | XCTAssert(CGRectEqualToRect(frame, twiceFlippedFrame));
51 | }
52 |
53 | - (void)testNegativeMDCRectHorizontallyFlipped {
54 | CGRect frame = CGRectMake(60.0, 50.0, -50.0, -30.0);
55 | CGRect flippedFrame = MDFRectFlippedHorizontally(frame, 100.0);
56 | CGRect validResultFrame = CGRectMake(40.0, 20.0, 50.0, 30.0);
57 |
58 | XCTAssert(CGRectEqualToRect(flippedFrame, validResultFrame));
59 | }
60 |
61 | - (void)testMDCRectFlippedForRTLRightToLeft {
62 | CGRect frame = CGRectMake(10.0, 20.0, 50.0, 30.0);
63 | CGFloat boundsWidth = 100.0;
64 | CGRect flippedFrame = MDFRectFlippedHorizontally(frame, boundsWidth);
65 | CGRect validResultFrame = CGRectMake(40.0, 20.0, 50.0, 30.0);
66 |
67 | XCTAssert(CGRectEqualToRect(flippedFrame, validResultFrame));
68 | }
69 |
70 | - (void)testMDCRectFlippedForRTLNegativeRightToLeft {
71 | CGRect frame = CGRectMake(60.0, 50.0, -50.0, -30.0);
72 | CGFloat boundsWidth = 100.0;
73 | CGRect flippedFrame = MDFRectFlippedHorizontally(frame, boundsWidth);
74 | CGRect validResultFrame = CGRectMake(40.0, 20.0, 50.0, 30.0);
75 |
76 | XCTAssert(CGRectEqualToRect(flippedFrame, validResultFrame));
77 | }
78 |
79 | - (void)testMDCInsetsMakeWithLayoutDirectionLeftToRight {
80 | UIEdgeInsets insets = MDFInsetsMakeWithLayoutDirection(10, 20, 30, 40, UIUserInterfaceLayoutDirectionLeftToRight);
81 | XCTAssertEqual(insets.left, 20);
82 | XCTAssertEqual(insets.right, 40);
83 | }
84 |
85 | - (void)testMDCInsetsMakeWithLayoutDirectionRightToLeft {
86 | UIEdgeInsets insets = MDFInsetsMakeWithLayoutDirection(10, 20, 30, 40, UIUserInterfaceLayoutDirectionRightToLeft);
87 | XCTAssertEqual(insets.left, 40);
88 | XCTAssertEqual(insets.right, 20);
89 | }
90 |
91 | - (void)testMDCRTLFlippedImagePortsRenderingMode {
92 | UIImage *image = [RTLTests standardImage];
93 | UIImage *flippedImage = [image mdf_imageWithHorizontallyFlippedOrientation];
94 |
95 | XCTAssertTrue(image.renderingMode == UIImageRenderingModeAutomatic);
96 | XCTAssertTrue(flippedImage.renderingMode == UIImageRenderingModeAutomatic);
97 |
98 | UIImage *templateImage = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
99 | UIImage *flippedTemplateImage = [templateImage mdf_imageWithHorizontallyFlippedOrientation];
100 |
101 | XCTAssertTrue(templateImage.renderingMode == UIImageRenderingModeAlwaysTemplate);
102 | XCTAssertTrue(flippedTemplateImage.renderingMode == UIImageRenderingModeAlwaysTemplate);
103 |
104 | UIImage *originalImage = [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
105 | UIImage *flippedOriginalImage = [originalImage mdf_imageWithHorizontallyFlippedOrientation];
106 |
107 | XCTAssertTrue(originalImage.renderingMode == UIImageRenderingModeAlwaysOriginal);
108 | XCTAssertTrue(flippedOriginalImage.renderingMode == UIImageRenderingModeAlwaysOriginal);
109 | }
110 |
111 | //TODO: (#6) Implement per-pixel comparison
112 | //- (void)testImageMirror {
113 | // UIImage *sourceImage = [RTLTests standardImage];
114 | // UIImage *flippedImage = [sourceImage mdf_imageWithHorizontallyFlippedOrientation];
115 | // UIImage *twiceFlippedImage = [flippedImage mdf_imageWithHorizontallyFlippedOrientation];
116 |
117 | // sourceImage != flippedImage
118 | // sourceImage == twiceFlippedImage
119 | //}
120 |
121 |
122 | // Pixel Image is a 1 x 1 red square
123 | + (UIImage *)pixelImage {
124 | CGRect frame = CGRectMake(0.0, 0.0, 1.0, 1.0);
125 |
126 | UIGraphicsBeginImageContext(frame.size);
127 |
128 | CGContextRef context = UIGraphicsGetCurrentContext();
129 |
130 | CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
131 | CGContextFillRect(context, frame);
132 |
133 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
134 | UIGraphicsEndImageContext();
135 |
136 | return image;
137 | }
138 |
139 | // Standard Image is a blue rectangle with a green line from top left to bottom right
140 | + (UIImage *)standardImage {
141 | static UIImage *image;
142 | static dispatch_once_t onceToken;
143 | dispatch_once(&onceToken, ^{
144 | CGRect frame = CGRectMake(0.0, 0.0, 60.0, 40.0);
145 |
146 | UIGraphicsBeginImageContext(frame.size);
147 |
148 | CGContextRef context = UIGraphicsGetCurrentContext();
149 |
150 | CGContextSetFillColorWithColor(context, [UIColor blueColor].CGColor);
151 | CGContextFillRect(context, frame);
152 |
153 | CGContextSetStrokeColorWithColor(context, [UIColor greenColor].CGColor);
154 | CGContextSetLineWidth(context, 1.0);
155 |
156 | CGContextMoveToPoint(context, 0.0, 0.0);
157 | CGContextAddLineToPoint(context, 60.0, 40.0);
158 |
159 | CGContextStrokePath(context);
160 |
161 | image = UIGraphicsGetImageFromCurrentImageContext();
162 | UIGraphicsEndImageContext();
163 | });
164 |
165 | return image;
166 | }
167 |
168 | @end
169 |
--------------------------------------------------------------------------------
/WORKSPACE:
--------------------------------------------------------------------------------
1 | # Copyright 2017-present The Material Foundation Authors. All Rights Reserved.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
16 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
17 |
18 | git_repository(
19 | name = "build_bazel_rules_apple",
20 | remote = "https://github.com/bazelbuild/rules_apple.git",
21 | commit = "19f031f09185e0fcd722c22e596d09bd6fff7944", # 0.19.0
22 | shallow_since = "1570721035 -0700", # 10-10-2019
23 | )
24 |
25 | load(
26 | "@build_bazel_rules_apple//apple:repositories.bzl",
27 | "apple_rules_dependencies",
28 | )
29 |
30 | apple_rules_dependencies()
31 |
32 | load(
33 | "@build_bazel_rules_swift//swift:repositories.bzl",
34 | "swift_rules_dependencies",
35 | )
36 |
37 | swift_rules_dependencies()
38 |
39 | load(
40 | "@build_bazel_apple_support//lib:repositories.bzl",
41 | "apple_support_dependencies",
42 | )
43 |
44 | apple_support_dependencies()
45 |
46 | git_repository(
47 | name = "bazel_ios_warnings",
48 | remote = "https://github.com/material-foundation/bazel_ios_warnings.git",
49 | commit = "c3f720c0838af1ee53299aa6efda87cf729146b4", # v3.0.0
50 | shallow_since = "1545400728 -0500" # 12-21-2018
51 | )
52 |
--------------------------------------------------------------------------------
/apple_framework_relative_headers.bzl:
--------------------------------------------------------------------------------
1 | """Bazel rules for supporting framework-relative header imports."""
2 |
3 | load(
4 | "@build_bazel_rules_apple//apple/internal:file_support.bzl",
5 | "file_support",
6 | )
7 |
8 | def _apple_framework_relative_headers_impl(ctx):
9 | """Implementation for apple_framework_relative_headers rule."""
10 | output_dir = ctx.attr.framework_name + "_apple_framework_relative_headers"
11 |
12 | outputs = []
13 | for f in ctx.files.hdrs:
14 | framework_path = "/".join([output_dir, ctx.attr.framework_name, f.basename])
15 | framework_header_file = ctx.actions.declare_file(framework_path)
16 | file_support.symlink(ctx, f, framework_header_file)
17 | outputs.append(framework_header_file)
18 |
19 | # Documentation of these implicit types can be found here:
20 | # ctx: https://docs.bazel.build/versions/master/skylark/lib/ctx.html
21 | # ctx.label: https://docs.bazel.build/versions/master/skylark/lib/Label.html
22 |
23 | include_dir = "/".join([
24 | ctx.configuration.bin_dir.path, ctx.label.workspace_root, ctx.label.package, output_dir])
25 | return [
26 | apple_common.new_objc_provider(
27 | header=depset(outputs),
28 | include=depset([include_dir]),
29 | ),
30 | DefaultInfo(files=depset(outputs)),
31 | ]
32 |
33 |
34 | apple_framework_relative_headers = rule(
35 | _apple_framework_relative_headers_impl,
36 | attrs = {
37 | "hdrs": attr.label_list(allow_files=[".h"], allow_empty=False),
38 | "framework_name": attr.string(mandatory=True),
39 | "_realpath": attr.label(
40 | cfg="host",
41 | allow_single_file=True,
42 | default=Label("@bazel_tools//tools/objc:realpath"),
43 | ),
44 | },
45 | )
46 | """Creates a directory structure suitable for framework-relative import
47 | statements.
48 |
49 | For example, one would be able to #import given the following rules:
50 |
51 | apple_framework_relative_headers(
52 | name = "FooFrameworkHeaders",
53 | hdrs = ["Source/Bar.h"],
54 | framework_name = "Foo",
55 | )
56 |
57 | objc_library(
58 | ...
59 | deps = [":FooFrameworkHeaders"],
60 | )
61 |
62 | Args:
63 | hdrs: The list of header files.
64 | framework_name: The name of the framework.
65 | """
66 |
--------------------------------------------------------------------------------