diff --git a/Example - search range/SearchTextFieldWithRange/.idea/SearchTextFieldWithRange.iml b/Example - search range/SearchTextFieldWithRange/.idea/SearchTextFieldWithRange.iml new file mode 100644 index 0000000..74121dc --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/.idea/SearchTextFieldWithRange.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/Example - search range/SearchTextFieldWithRange/.idea/misc.xml b/Example - search range/SearchTextFieldWithRange/.idea/misc.xml new file mode 100644 index 0000000..1ed671e --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/.idea/misc.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/Example - search range/SearchTextFieldWithRange/.idea/modules.xml b/Example - search range/SearchTextFieldWithRange/.idea/modules.xml new file mode 100644 index 0000000..cde4e54 --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/Example - search range/SearchTextFieldWithRange/.idea/workspace.xml b/Example - search range/SearchTextFieldWithRange/.idea/workspace.xml new file mode 100644 index 0000000..c88473c --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/.idea/workspace.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1624446189510 + + + + + + \ No newline at end of file diff --git a/Example - search range/SearchTextFieldWithRange/.idea/xcode.xml b/Example - search range/SearchTextFieldWithRange/.idea/xcode.xml new file mode 100644 index 0000000..a7e6b7a --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/.idea/xcode.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Example - search range/SearchTextFieldWithRange/Podfile b/Example - search range/SearchTextFieldWithRange/Podfile new file mode 100644 index 0000000..e61b52e --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/Podfile @@ -0,0 +1,8 @@ +# Uncomment the next line to define a global platform for your project +platform :ios, '9.0' + +target 'SearchTextFieldWithRange' do + + pod 'SearchTextField', :path => "../.." + +end diff --git a/Example - search range/SearchTextFieldWithRange/Podfile.lock b/Example - search range/SearchTextFieldWithRange/Podfile.lock new file mode 100644 index 0000000..c0e53ac --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/Podfile.lock @@ -0,0 +1,16 @@ +PODS: + - SearchTextField (1.2.4) + +DEPENDENCIES: + - SearchTextField (from `../..`) + +EXTERNAL SOURCES: + SearchTextField: + :path: "../.." + +SPEC CHECKSUMS: + SearchTextField: 40dc3cc57def5a211f263cac263622c163bbc25a + +PODFILE CHECKSUM: 51feecd399dd662d5705f4d0573350b7d2135287 + +COCOAPODS: 1.10.1 diff --git a/Example - search range/SearchTextFieldWithRange/Pods/Headers/Public/SearchTextField/SearchTextField-umbrella.h b/Example - search range/SearchTextFieldWithRange/Pods/Headers/Public/SearchTextField/SearchTextField-umbrella.h new file mode 120000 index 0000000..80bc9b3 --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/Pods/Headers/Public/SearchTextField/SearchTextField-umbrella.h @@ -0,0 +1 @@ +../../../Target Support Files/SearchTextField/SearchTextField-umbrella.h \ No newline at end of file diff --git a/Example - search range/SearchTextFieldWithRange/Pods/Headers/Public/SearchTextField/SearchTextField.modulemap b/Example - search range/SearchTextFieldWithRange/Pods/Headers/Public/SearchTextField/SearchTextField.modulemap new file mode 120000 index 0000000..cba7252 --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/Pods/Headers/Public/SearchTextField/SearchTextField.modulemap @@ -0,0 +1 @@ +../../../Target Support Files/SearchTextField/SearchTextField.modulemap \ No newline at end of file diff --git a/Example - search range/SearchTextFieldWithRange/Pods/Local Podspecs/SearchTextField.podspec.json b/Example - search range/SearchTextFieldWithRange/Pods/Local Podspecs/SearchTextField.podspec.json new file mode 100644 index 0000000..eea1076 --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/Pods/Local Podspecs/SearchTextField.podspec.json @@ -0,0 +1,24 @@ +{ + "name": "SearchTextField", + "version": "1.2.4", + "summary": "SearchTextField extends UITextField allowing you to add the autocomplete feature in a really easy way", + "swift_versions": "5.0", + "description": "Even though creating the autocomplete feature over a UITextField is not a big issue, dealing with screen rotation, keyboard position, the look and feel, etc, makes this task harder than expected.\n The idea behind SearchTextField is to help you adding this feature in just a few lines of code.\nSearchTextField supports two different modes: the classic dropdown list (by default) and the inline mode perfect for autocomplete email domains as an example.", + "homepage": "https://github.com/apasccon/SearchTextField", + "license": "MIT", + "authors": { + "Alejandro Pasccon": "apasccon@gmail.com" + }, + "source": { + "git": "https://github.com/apasccon/SearchTextField.git", + "tag": "1.2.4" + }, + "platforms": { + "ios": "9.0" + }, + "user_target_xcconfig": { + "ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES": "$(inherited)" + }, + "source_files": "SearchTextField/Classes/**/*", + "swift_version": "5.0" +} diff --git a/Example - search range/SearchTextFieldWithRange/Pods/Manifest.lock b/Example - search range/SearchTextFieldWithRange/Pods/Manifest.lock new file mode 100644 index 0000000..c0e53ac --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/Pods/Manifest.lock @@ -0,0 +1,16 @@ +PODS: + - SearchTextField (1.2.4) + +DEPENDENCIES: + - SearchTextField (from `../..`) + +EXTERNAL SOURCES: + SearchTextField: + :path: "../.." + +SPEC CHECKSUMS: + SearchTextField: 40dc3cc57def5a211f263cac263622c163bbc25a + +PODFILE CHECKSUM: 51feecd399dd662d5705f4d0573350b7d2135287 + +COCOAPODS: 1.10.1 diff --git a/Example - search range/SearchTextFieldWithRange/Pods/Pods.xcodeproj/project.pbxproj b/Example - search range/SearchTextFieldWithRange/Pods/Pods.xcodeproj/project.pbxproj new file mode 100644 index 0000000..39fb6b3 --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/Pods/Pods.xcodeproj/project.pbxproj @@ -0,0 +1,557 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 08C115638665B777FFBD88D96CC87DC0 /* Pods-SearchTextFieldWithRange-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 660C0828CD76DAAC36B0BA046400C8C9 /* Pods-SearchTextFieldWithRange-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1BE189F5A119D9FD3984BD787C406AD6 /* SearchTextField-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 89CA30D022F4B18FDF398E0E50692EB8 /* SearchTextField-dummy.m */; }; + 82ED71865861699150BAEB8855230502 /* Pods-SearchTextFieldWithRange-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 9FCB8AA857F5485C03F2B73B749AC99D /* Pods-SearchTextFieldWithRange-dummy.m */; }; + 96C111B59990CEB360EB178C35BA2149 /* SearchTextField-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 55CEED653F4AC52D33A5B7EE2F99A109 /* SearchTextField-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A0D4717FA665A92E588AE54EC4424AA7 /* SearchTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A983D273E5FC3E0DE4050583F0542DD /* SearchTextField.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 765F9FEA32BC26C66DCD0AF45274C6C4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8C3F94412D7198255213EB9BC85FFF6E; + remoteInfo = SearchTextField; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 11E992FEB65D89C320399BEF20B852E1 /* Pods-SearchTextFieldWithRange.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-SearchTextFieldWithRange.modulemap"; sourceTree = ""; }; + 1B42976F07046CF9A487A9680B18022B /* libPods-SearchTextFieldWithRange.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libPods-SearchTextFieldWithRange.a"; path = "libPods-SearchTextFieldWithRange.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1C1CB3DEDD3E75D68F9DF7C3C8481AD7 /* SearchTextField.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SearchTextField.debug.xcconfig; sourceTree = ""; }; + 27E38DF68C673A5EB8644FB6A9772F87 /* libSearchTextField.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libSearchTextField.a; path = libSearchTextField.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 309FEF81FD747F6EE2E73DED000745EA /* Pods-SearchTextFieldWithRange.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-SearchTextFieldWithRange.release.xcconfig"; sourceTree = ""; }; + 4581C69430A05E433EA2B32E0E9B358F /* SearchTextField.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SearchTextField.release.xcconfig; sourceTree = ""; }; + 4D538ACCE315C79C0E0195DC0CB2BE0E /* SearchTextField-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SearchTextField-prefix.pch"; sourceTree = ""; }; + 55CEED653F4AC52D33A5B7EE2F99A109 /* SearchTextField-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SearchTextField-umbrella.h"; sourceTree = ""; }; + 5A983D273E5FC3E0DE4050583F0542DD /* SearchTextField.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SearchTextField.swift; path = SearchTextField/Classes/SearchTextField.swift; sourceTree = ""; }; + 5EE861876CA49B510E0C5A55BECD607E /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; path = README.md; sourceTree = ""; }; + 660C0828CD76DAAC36B0BA046400C8C9 /* Pods-SearchTextFieldWithRange-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-SearchTextFieldWithRange-umbrella.h"; sourceTree = ""; }; + 68828DACA8AB90460584D18E0C90EE2F /* Pods-SearchTextFieldWithRange-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-SearchTextFieldWithRange-acknowledgements.plist"; sourceTree = ""; }; + 6EE3232C0043EF5511F2D9D660EC2C97 /* SearchTextField.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; path = SearchTextField.podspec; sourceTree = ""; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + 89CA30D022F4B18FDF398E0E50692EB8 /* SearchTextField-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SearchTextField-dummy.m"; sourceTree = ""; }; + 8A81A09180B5BD685E0F37E8A6DC7FD8 /* Pods-SearchTextFieldWithRange-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-SearchTextFieldWithRange-acknowledgements.markdown"; sourceTree = ""; }; + 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + 9FCB8AA857F5485C03F2B73B749AC99D /* Pods-SearchTextFieldWithRange-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-SearchTextFieldWithRange-dummy.m"; sourceTree = ""; }; + BAB8B7541B1B4C5958CB343141E6A35D /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE; sourceTree = ""; }; + CC4082D0B3926D5D5D9E831D142C6B42 /* SearchTextField.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SearchTextField.modulemap; sourceTree = ""; }; + D498BD0EAEF270C28184E60655872894 /* Pods-SearchTextFieldWithRange.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-SearchTextFieldWithRange.debug.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + B0F992E63E2EE6BBA39FCF1B3BF3913A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + BB9DD383131E21DB2890A19CCA9FEABF /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 0C5B7D3FE8102E96D0A22056D46194CA /* Pods-SearchTextFieldWithRange */ = { + isa = PBXGroup; + children = ( + 11E992FEB65D89C320399BEF20B852E1 /* Pods-SearchTextFieldWithRange.modulemap */, + 8A81A09180B5BD685E0F37E8A6DC7FD8 /* Pods-SearchTextFieldWithRange-acknowledgements.markdown */, + 68828DACA8AB90460584D18E0C90EE2F /* Pods-SearchTextFieldWithRange-acknowledgements.plist */, + 9FCB8AA857F5485C03F2B73B749AC99D /* Pods-SearchTextFieldWithRange-dummy.m */, + 660C0828CD76DAAC36B0BA046400C8C9 /* Pods-SearchTextFieldWithRange-umbrella.h */, + D498BD0EAEF270C28184E60655872894 /* Pods-SearchTextFieldWithRange.debug.xcconfig */, + 309FEF81FD747F6EE2E73DED000745EA /* Pods-SearchTextFieldWithRange.release.xcconfig */, + ); + name = "Pods-SearchTextFieldWithRange"; + path = "Target Support Files/Pods-SearchTextFieldWithRange"; + sourceTree = ""; + }; + 0DE789ED66A04BA9E731BE71C1F7EB99 /* Targets Support Files */ = { + isa = PBXGroup; + children = ( + 0C5B7D3FE8102E96D0A22056D46194CA /* Pods-SearchTextFieldWithRange */, + ); + name = "Targets Support Files"; + sourceTree = ""; + }; + 1C81B1DCCA4560F8126E962BB1EC4DEE /* Pod */ = { + isa = PBXGroup; + children = ( + BAB8B7541B1B4C5958CB343141E6A35D /* LICENSE */, + 5EE861876CA49B510E0C5A55BECD607E /* README.md */, + 6EE3232C0043EF5511F2D9D660EC2C97 /* SearchTextField.podspec */, + ); + name = Pod; + sourceTree = ""; + }; + 4E0217F400CA4A29F4073B0C4258683D /* Support Files */ = { + isa = PBXGroup; + children = ( + CC4082D0B3926D5D5D9E831D142C6B42 /* SearchTextField.modulemap */, + 89CA30D022F4B18FDF398E0E50692EB8 /* SearchTextField-dummy.m */, + 4D538ACCE315C79C0E0195DC0CB2BE0E /* SearchTextField-prefix.pch */, + 55CEED653F4AC52D33A5B7EE2F99A109 /* SearchTextField-umbrella.h */, + 1C1CB3DEDD3E75D68F9DF7C3C8481AD7 /* SearchTextField.debug.xcconfig */, + 4581C69430A05E433EA2B32E0E9B358F /* SearchTextField.release.xcconfig */, + ); + name = "Support Files"; + path = "Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/SearchTextField"; + sourceTree = ""; + }; + 5E8DD1339544D147930CDBB2AD602A72 /* Products */ = { + isa = PBXGroup; + children = ( + 1B42976F07046CF9A487A9680B18022B /* libPods-SearchTextFieldWithRange.a */, + 27E38DF68C673A5EB8644FB6A9772F87 /* libSearchTextField.a */, + ); + name = Products; + sourceTree = ""; + }; + 9AC2B02AE2D35DA9D18E7051A95DDA72 /* Development Pods */ = { + isa = PBXGroup; + children = ( + D80DBFC10198E763C5941F563EC62D92 /* SearchTextField */, + ); + name = "Development Pods"; + sourceTree = ""; + }; + CF1408CF629C7361332E53B88F7BD30C = { + isa = PBXGroup; + children = ( + 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */, + 9AC2B02AE2D35DA9D18E7051A95DDA72 /* Development Pods */, + D89477F20FB1DE18A04690586D7808C4 /* Frameworks */, + 5E8DD1339544D147930CDBB2AD602A72 /* Products */, + 0DE789ED66A04BA9E731BE71C1F7EB99 /* Targets Support Files */, + ); + sourceTree = ""; + }; + D80DBFC10198E763C5941F563EC62D92 /* SearchTextField */ = { + isa = PBXGroup; + children = ( + 5A983D273E5FC3E0DE4050583F0542DD /* SearchTextField.swift */, + 1C81B1DCCA4560F8126E962BB1EC4DEE /* Pod */, + 4E0217F400CA4A29F4073B0C4258683D /* Support Files */, + ); + name = SearchTextField; + path = ../../..; + sourceTree = ""; + }; + D89477F20FB1DE18A04690586D7808C4 /* Frameworks */ = { + isa = PBXGroup; + children = ( + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 6CDE9ED12D19E2D5A1515C195DAD6F4C /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 08C115638665B777FFBD88D96CC87DC0 /* Pods-SearchTextFieldWithRange-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DDF6679D18178B4290FAD28CFA765C82 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 96C111B59990CEB360EB178C35BA2149 /* SearchTextField-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 8C3F94412D7198255213EB9BC85FFF6E /* SearchTextField */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1704360E5C211FC35A945A314648B6FB /* Build configuration list for PBXNativeTarget "SearchTextField" */; + buildPhases = ( + DDF6679D18178B4290FAD28CFA765C82 /* Headers */, + FA50F4A03EEC9507FCA0FFA9F7568125 /* Sources */, + B0F992E63E2EE6BBA39FCF1B3BF3913A /* Frameworks */, + 79E3D7BAD8442FE65E46C9B07EDAFB58 /* Copy generated compatibility header */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SearchTextField; + productName = SearchTextField; + productReference = 27E38DF68C673A5EB8644FB6A9772F87 /* libSearchTextField.a */; + productType = "com.apple.product-type.library.static"; + }; + 9E49E7F5EE544CFB8122B25541AC4192 /* Pods-SearchTextFieldWithRange */ = { + isa = PBXNativeTarget; + buildConfigurationList = 498FB8FAD075418042838AB89DF43A5C /* Build configuration list for PBXNativeTarget "Pods-SearchTextFieldWithRange" */; + buildPhases = ( + 6CDE9ED12D19E2D5A1515C195DAD6F4C /* Headers */, + CCDA852162BB1ECA7B1E524D629674C6 /* Sources */, + BB9DD383131E21DB2890A19CCA9FEABF /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + E436B85BA8B1F92FD505B01FE51BE45E /* PBXTargetDependency */, + ); + name = "Pods-SearchTextFieldWithRange"; + productName = "Pods-SearchTextFieldWithRange"; + productReference = 1B42976F07046CF9A487A9680B18022B /* libPods-SearchTextFieldWithRange.a */; + productType = "com.apple.product-type.library.static"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + BFDFE7DC352907FC980B868725387E98 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + }; + buildConfigurationList = 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = CF1408CF629C7361332E53B88F7BD30C; + productRefGroup = 5E8DD1339544D147930CDBB2AD602A72 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 9E49E7F5EE544CFB8122B25541AC4192 /* Pods-SearchTextFieldWithRange */, + 8C3F94412D7198255213EB9BC85FFF6E /* SearchTextField */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXShellScriptBuildPhase section */ + 79E3D7BAD8442FE65E46C9B07EDAFB58 /* Copy generated compatibility header */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${DERIVED_SOURCES_DIR}/${PRODUCT_MODULE_NAME}-Swift.h", + "${PODS_ROOT}/Headers/Public/SearchTextField/SearchTextField.modulemap", + "${PODS_ROOT}/Headers/Public/SearchTextField/SearchTextField-umbrella.h", + ); + name = "Copy generated compatibility header"; + outputFileListPaths = ( + ); + outputPaths = ( + "${BUILT_PRODUCTS_DIR}/${PRODUCT_MODULE_NAME}.modulemap", + "${BUILT_PRODUCTS_DIR}/SearchTextField-umbrella.h", + "${BUILT_PRODUCTS_DIR}/Swift Compatibility Header/${PRODUCT_MODULE_NAME}-Swift.h", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "COMPATIBILITY_HEADER_PATH=\"${BUILT_PRODUCTS_DIR}/Swift Compatibility Header/${PRODUCT_MODULE_NAME}-Swift.h\"\nMODULE_MAP_PATH=\"${BUILT_PRODUCTS_DIR}/${PRODUCT_MODULE_NAME}.modulemap\"\n\nditto \"${DERIVED_SOURCES_DIR}/${PRODUCT_MODULE_NAME}-Swift.h\" \"${COMPATIBILITY_HEADER_PATH}\"\nditto \"${PODS_ROOT}/Headers/Public/SearchTextField/SearchTextField.modulemap\" \"${MODULE_MAP_PATH}\"\nditto \"${PODS_ROOT}/Headers/Public/SearchTextField/SearchTextField-umbrella.h\" \"${BUILT_PRODUCTS_DIR}\"\nprintf \"\\n\\nmodule ${PRODUCT_MODULE_NAME}.Swift {\\n header \\\"${COMPATIBILITY_HEADER_PATH}\\\"\\n requires objc\\n}\\n\" >> \"${MODULE_MAP_PATH}\"\n"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + CCDA852162BB1ECA7B1E524D629674C6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 82ED71865861699150BAEB8855230502 /* Pods-SearchTextFieldWithRange-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FA50F4A03EEC9507FCA0FFA9F7568125 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1BE189F5A119D9FD3984BD787C406AD6 /* SearchTextField-dummy.m in Sources */, + A0D4717FA665A92E588AE54EC4424AA7 /* SearchTextField.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + E436B85BA8B1F92FD505B01FE51BE45E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SearchTextField; + target = 8C3F94412D7198255213EB9BC85FFF6E /* SearchTextField */; + targetProxy = 765F9FEA32BC26C66DCD0AF45274C6C4 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 25AD9454612BF454A1E3DC4CD4FA8C6D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "POD_CONFIGURATION_DEBUG=1", + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRIP_INSTALLED_PRODUCT = NO; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + SYMROOT = "${SRCROOT}/../build"; + }; + name = Debug; + }; + 505B08562CFA7DFF5B4FF5B43BC2B11D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 309FEF81FD747F6EE2E73DED000745EA /* Pods-SearchTextFieldWithRange.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-SearchTextFieldWithRange/Pods-SearchTextFieldWithRange.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 8E8CBA5D103C267523CC65EF74D57286 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4581C69430A05E433EA2B32E0E9B358F /* SearchTextField.release.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + GCC_PREFIX_HEADER = "Target Support Files/SearchTextField/SearchTextField-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MODULEMAP_FILE = Headers/Public/SearchTextField/SearchTextField.modulemap; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PRIVATE_HEADERS_FOLDER_PATH = ""; + PRODUCT_MODULE_NAME = SearchTextField; + PRODUCT_NAME = SearchTextField; + PUBLIC_HEADERS_FOLDER_PATH = ""; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 9C6FC260EF62A01459722E49E8D42072 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 1C1CB3DEDD3E75D68F9DF7C3C8481AD7 /* SearchTextField.debug.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + GCC_PREFIX_HEADER = "Target Support Files/SearchTextField/SearchTextField-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MODULEMAP_FILE = Headers/Public/SearchTextField/SearchTextField.modulemap; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PRIVATE_HEADERS_FOLDER_PATH = ""; + PRODUCT_MODULE_NAME = SearchTextField; + PRODUCT_NAME = SearchTextField; + PUBLIC_HEADERS_FOLDER_PATH = ""; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + CA547D2C7E9A8A153DC2B27FBE00B112 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "POD_CONFIGURATION_RELEASE=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRIP_INSTALLED_PRODUCT = NO; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + SYMROOT = "${SRCROOT}/../build"; + }; + name = Release; + }; + F3F76253CB2C7192D0F39F2ED603ABEF /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D498BD0EAEF270C28184E60655872894 /* Pods-SearchTextFieldWithRange.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-SearchTextFieldWithRange/Pods-SearchTextFieldWithRange.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1704360E5C211FC35A945A314648B6FB /* Build configuration list for PBXNativeTarget "SearchTextField" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9C6FC260EF62A01459722E49E8D42072 /* Debug */, + 8E8CBA5D103C267523CC65EF74D57286 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 25AD9454612BF454A1E3DC4CD4FA8C6D /* Debug */, + CA547D2C7E9A8A153DC2B27FBE00B112 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 498FB8FAD075418042838AB89DF43A5C /* Build configuration list for PBXNativeTarget "Pods-SearchTextFieldWithRange" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F3F76253CB2C7192D0F39F2ED603ABEF /* Debug */, + 505B08562CFA7DFF5B4FF5B43BC2B11D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = BFDFE7DC352907FC980B868725387E98 /* Project object */; +} diff --git a/Example - search range/SearchTextFieldWithRange/Pods/SearchTextField/LICENSE b/Example - search range/SearchTextFieldWithRange/Pods/SearchTextField/LICENSE new file mode 100644 index 0000000..d2ceeea --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/Pods/SearchTextField/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2016 Alejandro Pasccon + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/Example - search range/SearchTextFieldWithRange/Pods/SearchTextField/README.md b/Example - search range/SearchTextFieldWithRange/Pods/SearchTextField/README.md new file mode 100644 index 0000000..409e9d9 --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/Pods/SearchTextField/README.md @@ -0,0 +1,196 @@ +![alt_tag](https://raw.githubusercontent.com/apasccon/SearchTextField/master/Example/SearchTextField/SearchTextField.png) + +# SearchTextField + +[![Version](https://img.shields.io/cocoapods/v/SearchTextField.svg?style=flat)](http://cocoapods.org/pods/SearchTextField) +[![License](https://img.shields.io/cocoapods/l/SearchTextField.svg?style=flat)](http://cocoapods.org/pods/SearchTextField) +[![Platform](https://img.shields.io/cocoapods/p/SearchTextField.svg?style=flat)](http://cocoapods.org/pods/SearchTextField) + +## Overview + +**SearchTextField** is a subclass of UITextField, written in Swift that makes really easy the ability to show an autocomplete suggestions list. +You can decide wether to show the list as soon as the field is focused or when the user starts typing. +You can also detects when the user stops typing, very useful when you can get a suggestion list from a remote server. + +**New Feature!** +Now you can make suggestions "inline", showing the first matched result as the placeholder (instead of the results list) and selecting it when the user touches the enter key. + +------ +![alt_tag](https://raw.githubusercontent.com/apasccon/SearchTextField/master/Example/SearchTextField/SearchTextField_Demo.gif) + +## Requirements + +* iOS 9 + +## Installation + +SearchTextField is available through [CocoaPods](http://cocoapods.org). To install +it, simply add the following line to your Podfile: + +```swift +use_frameworks! + +pod "SearchTextField" +``` + +### Manual installation + +Just import SearchTextField.swift into your project + +## Usage + +### You can use it in the simplest way... + +```swift +import SearchTextField + +// Connect your IBOutlet... +@IBOutlet weak var mySearchTextField: SearchTextField! + +// ...or create it manually +let mySearchTextField = SearchTextField(frame: CGRectMake(10, 100, 200, 40)) + +// Set the array of strings you want to suggest +mySearchTextField.filterStrings(["Red", "Blue", "Yellow"]) +``` +### ...or you can customize it as you want + +```swift +// Show also a subtitle and an image for each suggestion: + +let item1 = SearchTextFieldItem(title: "Blue", subtitle: "Color", image: UIImage(named: "icon_blue")) +let item2 = SearchTextFieldItem(title: "Red", subtitle: "Color", image: UIImage(named: "icon_red")) +let item3 = SearchTextFieldItem(title: "Yellow", subtitle: "Color", image: UIImage(named: "icon_yellow")) +mySearchTextField.filterItems([item1, item2, item3]) + +// Set a visual theme (SearchTextFieldTheme). By default it's the light theme +mySearchTextField.theme = SearchTextFieldTheme.darkTheme() + +// Modify current theme properties +mySearchTextField.theme.font = UIFont.systemFontOfSize(12) +mySearchTextField.theme.bgColor = UIColor (red: 0.9, green: 0.9, blue: 0.9, alpha: 0.3) +mySearchTextField.theme.borderColor = UIColor (red: 0.9, green: 0.9, blue: 0.9, alpha: 1) +mySearchTextField.theme.separatorColor = UIColor (red: 0.9, green: 0.9, blue: 0.9, alpha: 0.5) +mySearchTextField.theme.cellHeight = 50 + +// Set specific comparision options - Default: .caseInsensitive +mySearchTextField.comparisonOptions = [.caseInsensitive] + +// Set the max number of results. By default it's not limited +mySearchTextField.maxNumberOfResults = 5 + +// You can also limit the max height of the results list +mySearchTextField.maxResultsListHeight = 200 + +// Customize the way it highlights the search string. By default it bolds the string +mySearchTextField.highlightAttributes = [NSBackgroundColorAttributeName: UIColor.yellowColor(), NSFontAttributeName:UIFont.boldSystemFontOfSize(12)] + +// Handle what happens when the user picks an item. By default the title is set to the text field +mySearchTextField.itemSelectionHandler = {item, itemPosition in + mySearchTextField.text = item.title +} + +// You can force the results list to support RTL languages - Default: false +mySearchTextField.forceRightToLeft = true + +// Show the list of results as soon as the user makes focus - Default: false +mySearchTextField.startVisible = true + +// ...or show the list of results even without user's interaction as soon as created - Default: false +mySearchTextField.startVisibleWithoutInteraction = true + +// Start filtering after an specific number of characters - Default: 0 +mySearchTextField.minCharactersNumberToStartFiltering = 3 + +// Force to show the results list without filtering (but highlighting) +mySearchTextField.forceNoFiltering = true + +// Explicitly hide the results list +mySearchTextField.hideResultsList() + +/** +* Update data source when the user stops typing. +* It's useful when you want to retrieve results from a remote server while typing +* (but only when the user stops doing it) +**/ +mySearchTextField.userStoppedTypingHandler = { + if let criteria = self.mySearchTextField.text { + if criteria.characters.count > 1 { + + // Show the loading indicator + self.mySearchTextField.showLoadingIndicator() + + self.searchMoreItemsInBackground(criteria) { results in + // Set new items to filter + self.mySearchTextField.filterItems(results) + + // Hide loading indicator + self.mySearchTextField.stopLoadingIndicator() + } + } + } +} + +// Handle item selection - Default behaviour: item title set to the text field +mySearchTextField.itemSelectionHandler = { filteredResults, itemPosition in + // Just in case you need the item position + let item = filteredResults[itemPosition] + print("Item at position \(itemPosition): \(item.title)") + + // Do whatever you want with the picked item + self.mySearchTextField.text = item.title +} + +// Define a results list header - Default: nothing +let header = UILabel(frame: CGRect(x: 0, y: 0, width: acronymTextField.frame.width, height: 30)) +header.backgroundColor = UIColor.lightGray.withAlphaComponent(0.3) +header.textAlignment = .center +header.font = UIFont.systemFont(ofSize: 14) +header.text = "Pick your option" +mySearchTextField.resultsListHeader = header + + + +``` + +### New feature: show the first matched result as placeholder (inline mode) + +```swift +// Set the array of strings you want to suggest +mySearchTextField.filterStrings(["Red", "Blue", "Yellow"]) + +// Then set the inline mode in true +mySearchTextField.inlineMode = true +``` + +### New feature: autocomplete from, for example, a list of email domains + +```swift +emailInlineTextField.inlineMode = true +emailInlineTextField.startFilteringAfter = "@" +emailInlineTextField.startSuggestingInmediately = true +emailInlineTextField.filterStrings(["gmail.com", "yahoo.com", "yahoo.com.ar"]) +``` + +## Swift Versions + +Swift 5 supported from 1.2.3 version. + +Swift 4 supported from 1.2.0 version. + +Install v1.0.0 if you need to support Swift 2.3. + +Install v1.0.2 and above if you want to support Swift 3. + + +## Demo + +Check out the Example project. + +## Author + +Alejandro Pasccon, apasccon@gmail.com + +## License + +SearchTextField is available under the MIT license. See the LICENSE file for more info. diff --git a/Example - search range/SearchTextFieldWithRange/Pods/SearchTextField/SearchTextField/Classes/SearchTextField.swift b/Example - search range/SearchTextFieldWithRange/Pods/SearchTextField/SearchTextField/Classes/SearchTextField.swift new file mode 100755 index 0000000..9cf8f55 --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/Pods/SearchTextField/SearchTextField/Classes/SearchTextField.swift @@ -0,0 +1,680 @@ +// +// SearchTextField.swift +// SearchTextField +// +// Created by Alejandro Pasccon on 4/20/16. +// Copyright © 2016 Alejandro Pasccon. All rights reserved. +// + +import UIKit + +open class SearchTextField: UITextField { + + //////////////////////////////////////////////////////////////////////// + // Public interface + + /// Maximum number of results to be shown in the suggestions list + open var maxNumberOfResults = 0 + + /// Maximum height of the results list + open var maxResultsListHeight = 0 + + /// Indicate if this field has been interacted with yet + open var interactedWith = false + + /// Indicate if keyboard is showing or not + open var keyboardIsShowing = false + + /// How long to wait before deciding typing has stopped + open var typingStoppedDelay = 0.8 + + /// Set your custom visual theme, or just choose between pre-defined SearchTextFieldTheme.lightTheme() and SearchTextFieldTheme.darkTheme() themes + open var theme = SearchTextFieldTheme.lightTheme() { + didSet { + tableView?.reloadData() + + if let placeholderColor = theme.placeholderColor { + if let placeholderString = placeholder { + self.attributedPlaceholder = NSAttributedString(string: placeholderString, attributes: [NSAttributedString.Key.foregroundColor: placeholderColor]) + } + + self.placeholderLabel?.textColor = placeholderColor + } + + if let hightlightedFont = self.highlightAttributes[.font] as? UIFont { + self.highlightAttributes[.font] = hightlightedFont.withSize(self.theme.font.pointSize) + } + } + } + + /// Show the suggestions list without filter when the text field is focused + open var startVisible = false + + /// Show the suggestions list without filter even if the text field is not focused + open var startVisibleWithoutInteraction = false { + didSet { + if startVisibleWithoutInteraction { + textFieldDidChange() + } + } + } + + /// Set an array of SearchTextFieldItem's to be used for suggestions + open func filterItems(_ items: [SearchTextFieldItem]) { + filterDataSource = items + } + + /// Set an array of strings to be used for suggestions + open func filterStrings(_ strings: [String]) { + var items = [SearchTextFieldItem]() + + for value in strings { + items.append(SearchTextFieldItem(title: value)) + } + + filterItems(items) + } + + /// Closure to handle when the user pick an item + open var itemSelectionHandler: SearchTextFieldItemHandler? + + /// Closure to handle when the user stops typing + open var userStoppedTypingHandler: (() -> Void)? + + /// Set your custom set of attributes in order to highlight the string found in each item + open var highlightAttributes: [NSAttributedString.Key: AnyObject] = [.font: UIFont.boldSystemFont(ofSize: 10)] + + /// Start showing the default loading indicator, useful for searches that take some time. + open func showLoadingIndicator() { + self.rightViewMode = .always + indicator.startAnimating() + } + + /// Force the results list to adapt to RTL languages + open var forceRightToLeft = false + + /// Hide the default loading indicator + open func stopLoadingIndicator() { + self.rightViewMode = .never + indicator.stopAnimating() + } + + /// When InlineMode is true, the suggestions appear in the same line than the entered string. It's useful for email domains suggestion for example. + open var inlineMode: Bool = false { + didSet { + if inlineMode == true { + autocorrectionType = .no + spellCheckingType = .no + } + } + } + + /// Only valid when InlineMode is true. The suggestions appear after typing the provided string (or even better a character like '@') + open var startFilteringAfter: String? + + /// Min number of characters to start filtering + open var minCharactersNumberToStartFiltering: Int = 0 + + /// Force no filtering (display the entire filtered data source) + open var forceNoFiltering: Bool = false + + /// If startFilteringAfter is set, and startSuggestingImmediately is true, the list of suggestions appear immediately + open var startSuggestingImmediately = false + + /// Allow to decide the comparision options + open var comparisonOptions: NSString.CompareOptions = [.caseInsensitive] + + /// Set the results list's header + open var resultsListHeader: UIView? + + // Move the table around to customize for your layout + open var tableXOffset: CGFloat = 0.0 + open var tableYOffset: CGFloat = 0.0 + open var tableCornerRadius: CGFloat = 2.0 + open var tableBottomMargin: CGFloat = 10.0 + + //////////////////////////////////////////////////////////////////////// + // Private implementation + + fileprivate var tableView: UITableView? + fileprivate var shadowView: UIView? + fileprivate var direction: Direction = .down + fileprivate var fontConversionRate: CGFloat = 0.7 + fileprivate var keyboardFrame: CGRect? + fileprivate var timer: Timer? = nil + fileprivate var placeholderLabel: UILabel? + fileprivate static let cellIdentifier = "APSearchTextFieldCell" + fileprivate let indicator = UIActivityIndicatorView(style: .gray) + fileprivate var maxTableViewSize: CGFloat = 0 + + fileprivate var filteredResults = [SearchTextFieldItem]() + fileprivate var filterDataSource = [SearchTextFieldItem]() { + didSet { + filter(forceShowAll: forceNoFiltering) + buildSearchTableView() + + if startVisibleWithoutInteraction { + textFieldDidChange() + } + } + } + + fileprivate var currentInlineItem = "" + + deinit { + NotificationCenter.default.removeObserver(self) + } + + open override func willMove(toWindow newWindow: UIWindow?) { + super.willMove(toWindow: newWindow) + tableView?.removeFromSuperview() + } + + override open func willMove(toSuperview newSuperview: UIView?) { + super.willMove(toSuperview: newSuperview) + + self.addTarget(self, action: #selector(SearchTextField.textFieldDidChange), for: .editingChanged) + self.addTarget(self, action: #selector(SearchTextField.textFieldDidBeginEditing), for: .editingDidBegin) + self.addTarget(self, action: #selector(SearchTextField.textFieldDidEndEditing), for: .editingDidEnd) + self.addTarget(self, action: #selector(SearchTextField.textFieldDidEndEditingOnExit), for: .editingDidEndOnExit) + + NotificationCenter.default.addObserver(self, selector: #selector(SearchTextField.keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(SearchTextField.keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(SearchTextField.keyboardDidChangeFrame(_:)), name: UIResponder.keyboardDidChangeFrameNotification, object: nil) + } + + override open func layoutSubviews() { + super.layoutSubviews() + + if inlineMode { + buildPlaceholderLabel() + } else { + buildSearchTableView() + } + + // Create the loading indicator + indicator.hidesWhenStopped = true + self.rightView = indicator + } + + override open func rightViewRect(forBounds bounds: CGRect) -> CGRect { + var rightFrame = super.rightViewRect(forBounds: bounds) + rightFrame.origin.x -= 5 + return rightFrame + } + + // Create the filter table and shadow view + fileprivate func buildSearchTableView() { + guard let tableView = tableView, let shadowView = shadowView else { + self.tableView = UITableView(frame: CGRect.zero) + self.shadowView = UIView(frame: CGRect.zero) + buildSearchTableView() + return + } + + tableView.layer.masksToBounds = true + tableView.layer.borderWidth = theme.borderWidth > 0 ? theme.borderWidth : 0.5 + tableView.dataSource = self + tableView.delegate = self + tableView.separatorInset = UIEdgeInsets.zero + tableView.tableHeaderView = resultsListHeader + if forceRightToLeft { + tableView.semanticContentAttribute = .forceRightToLeft + } + + shadowView.backgroundColor = UIColor.lightText + shadowView.layer.shadowColor = UIColor.black.cgColor + shadowView.layer.shadowOffset = CGSize.zero + shadowView.layer.shadowOpacity = 1 + + self.window?.addSubview(tableView) + + redrawSearchTableView() + } + + fileprivate func buildPlaceholderLabel() { + var newRect = self.placeholderRect(forBounds: self.bounds) + var caretRect = self.caretRect(for: self.beginningOfDocument) + let textRect = self.textRect(forBounds: self.bounds) + + if let range = textRange(from: beginningOfDocument, to: endOfDocument) { + caretRect = self.firstRect(for: range) + } + + newRect.origin.x = caretRect.origin.x + caretRect.size.width + textRect.origin.x + newRect.size.width = newRect.size.width - newRect.origin.x + + if let placeholderLabel = placeholderLabel { + placeholderLabel.font = self.font + placeholderLabel.frame = newRect + } else { + placeholderLabel = UILabel(frame: newRect) + placeholderLabel?.font = self.font + placeholderLabel?.backgroundColor = UIColor.clear + placeholderLabel?.lineBreakMode = .byClipping + + if let placeholderColor = self.attributedPlaceholder?.attribute(NSAttributedString.Key.foregroundColor, at: 0, effectiveRange: nil) as? UIColor { + placeholderLabel?.textColor = placeholderColor + } else { + placeholderLabel?.textColor = UIColor ( red: 0.8, green: 0.8, blue: 0.8, alpha: 1.0 ) + } + + self.addSubview(placeholderLabel!) + } + } + + // Re-set frames and theme colors + fileprivate func redrawSearchTableView() { + if inlineMode { + tableView?.isHidden = true + return + } + + if let tableView = tableView { + guard let frame = self.superview?.convert(self.frame, to: nil) else { return } + + //TableViews use estimated cell heights to calculate content size until they + // are on-screen. We must set this to the theme cell height to avoid getting an + // incorrect contentSize when we have specified non-standard fonts and/or + // cellHeights in the theme. We do it here to ensure updates to these settings + // are recognized if changed after the tableView is created + tableView.estimatedRowHeight = theme.cellHeight + if self.direction == .down { + + var tableHeight: CGFloat = 0 + if keyboardIsShowing, let keyboardHeight = keyboardFrame?.size.height { + tableHeight = min((tableView.contentSize.height), (UIScreen.main.bounds.size.height - frame.origin.y - frame.height - keyboardHeight)) + } else { + tableHeight = min((tableView.contentSize.height), (UIScreen.main.bounds.size.height - frame.origin.y - frame.height)) + } + + if maxResultsListHeight > 0 { + tableHeight = min(tableHeight, CGFloat(maxResultsListHeight)) + } + + // Set a bottom margin of 10p + if tableHeight < tableView.contentSize.height { + tableHeight -= tableBottomMargin + } + + var tableViewFrame = CGRect(x: 0, y: 0, width: frame.size.width - 4, height: tableHeight) + tableViewFrame.origin = self.convert(tableViewFrame.origin, to: nil) + tableViewFrame.origin.x += 2 + tableXOffset + tableViewFrame.origin.y += frame.size.height + 2 + tableYOffset + self.tableView?.frame.origin = tableViewFrame.origin // Avoid animating from (0, 0) when displaying at launch + UIView.animate(withDuration: 0.2, animations: { [weak self] in + self?.tableView?.frame = tableViewFrame + }) + + var shadowFrame = CGRect(x: 0, y: 0, width: frame.size.width - 6, height: 1) + shadowFrame.origin = self.convert(shadowFrame.origin, to: nil) + shadowFrame.origin.x += 3 + shadowFrame.origin.y = tableView.frame.origin.y + shadowView!.frame = shadowFrame + } else { + let tableHeight = min((tableView.contentSize.height), (UIScreen.main.bounds.size.height - frame.origin.y - theme.cellHeight)) + UIView.animate(withDuration: 0.2, animations: { [weak self] in + self?.tableView?.frame = CGRect(x: frame.origin.x + 2, y: (frame.origin.y - tableHeight), width: frame.size.width - 4, height: tableHeight) + self?.shadowView?.frame = CGRect(x: frame.origin.x + 3, y: (frame.origin.y + 3), width: frame.size.width - 6, height: 1) + }) + } + + superview?.bringSubviewToFront(tableView) + superview?.bringSubviewToFront(shadowView!) + + if self.isFirstResponder { + superview?.bringSubviewToFront(self) + } + + tableView.layer.borderColor = theme.borderColor.cgColor + tableView.layer.cornerRadius = tableCornerRadius + tableView.separatorColor = theme.separatorColor + tableView.backgroundColor = theme.bgColor + + tableView.reloadData() + } + } + + // Handle keyboard events + @objc open func keyboardWillShow(_ notification: Notification) { + if !keyboardIsShowing && isEditing { + keyboardIsShowing = true + keyboardFrame = ((notification as NSNotification).userInfo![UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue + interactedWith = true + prepareDrawTableResult() + } + } + + @objc open func keyboardWillHide(_ notification: Notification) { + if keyboardIsShowing { + keyboardIsShowing = false + direction = .down + redrawSearchTableView() + } + } + + @objc open func keyboardDidChangeFrame(_ notification: Notification) { + DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in + self?.keyboardFrame = ((notification as NSNotification).userInfo![UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue + self?.prepareDrawTableResult() + } + } + + @objc open func typingDidStop() { + self.userStoppedTypingHandler?() + } + + // Handle text field changes + @objc open func textFieldDidChange() { + if !inlineMode && tableView == nil { + buildSearchTableView() + } + + interactedWith = true + + // Detect pauses while typing + timer?.invalidate() + timer = Timer.scheduledTimer(timeInterval: typingStoppedDelay, target: self, selector: #selector(SearchTextField.typingDidStop), userInfo: self, repeats: false) + + if text!.isEmpty { + clearResults() + tableView?.reloadData() + if startVisible || startVisibleWithoutInteraction { + filter(forceShowAll: true) + } + self.placeholderLabel?.text = "" + } else { + filter(forceShowAll: forceNoFiltering) + prepareDrawTableResult() + } + + buildPlaceholderLabel() + } + + @objc open func textFieldDidBeginEditing() { + if (startVisible || startVisibleWithoutInteraction) && text!.isEmpty { + clearResults() + filter(forceShowAll: true) + } + placeholderLabel?.attributedText = nil + } + + @objc open func textFieldDidEndEditing() { + clearResults() + tableView?.reloadData() + placeholderLabel?.attributedText = nil + } + + @objc open func textFieldDidEndEditingOnExit() { + if let firstElement = filteredResults.first { + if let itemSelectionHandler = self.itemSelectionHandler { + itemSelectionHandler(filteredResults, 0) + } + else { + if inlineMode, let filterAfter = startFilteringAfter { + let stringElements = self.text?.components(separatedBy: filterAfter) + + self.text = stringElements!.first! + filterAfter + firstElement.title + } else { + self.text = firstElement.title + } + } + } + } + + open func hideResultsList() { + if let tableFrame:CGRect = tableView?.frame { + let newFrame = CGRect(x: tableFrame.origin.x, y: tableFrame.origin.y, width: tableFrame.size.width, height: 0.0) + UIView.animate(withDuration: 0.2, animations: { [weak self] in + self?.tableView?.frame = newFrame + }) + + } + } + + fileprivate func filter(forceShowAll addAll: Bool) { + clearResults() + + if text!.count < minCharactersNumberToStartFiltering { + return + } + + for i in 0 ..< filterDataSource.count { + + let item = filterDataSource[i] + + if !inlineMode { + // Find text in title and subtitle + let titleFilterRange = (item.title as NSString).range(of: text!, options: comparisonOptions) + let subtitleFilterRange = item.subtitle != nil ? (item.subtitle! as NSString).range(of: text!, options: comparisonOptions) : NSMakeRange(NSNotFound, 0) + + if titleFilterRange.location != NSNotFound || subtitleFilterRange.location != NSNotFound || addAll { + item.attributedTitle = NSMutableAttributedString(string: item.title) + item.attributedSubtitle = NSMutableAttributedString(string: (item.subtitle != nil ? item.subtitle! : "")) + + item.attributedTitle!.setAttributes(highlightAttributes, range: titleFilterRange) + + if subtitleFilterRange.location != NSNotFound { + item.attributedSubtitle!.setAttributes(highlightAttributesForSubtitle(), range: subtitleFilterRange) + } + + filteredResults.append(item) + } + } else { + var textToFilter = text!.lowercased() + + if inlineMode, let filterAfter = startFilteringAfter { + if let suffixToFilter = textToFilter.components(separatedBy: filterAfter).last, (suffixToFilter != "" || startSuggestingImmediately == true), textToFilter != suffixToFilter { + textToFilter = suffixToFilter + } else { + placeholderLabel?.text = "" + return + } + } + + if item.title.lowercased().hasPrefix(textToFilter) { + let indexFrom = textToFilter.index(textToFilter.startIndex, offsetBy: textToFilter.count) + let itemSuffix = item.title[indexFrom...] + + item.attributedTitle = NSMutableAttributedString(string: String(itemSuffix)) + filteredResults.append(item) + } + } + } + + tableView?.reloadData() + + if inlineMode { + handleInlineFiltering() + } + } + + // Clean filtered results + fileprivate func clearResults() { + filteredResults.removeAll() + tableView?.removeFromSuperview() + } + + // Look for Font attribute, and if it exists, adapt to the subtitle font size + fileprivate func highlightAttributesForSubtitle() -> [NSAttributedString.Key: AnyObject] { + var highlightAttributesForSubtitle = [NSAttributedString.Key: AnyObject]() + + for attr in highlightAttributes { + if attr.0 == NSAttributedString.Key.font { + let fontName = (attr.1 as! UIFont).fontName + let pointSize = (attr.1 as! UIFont).pointSize * fontConversionRate + highlightAttributesForSubtitle[attr.0] = UIFont(name: fontName, size: pointSize) + } else { + highlightAttributesForSubtitle[attr.0] = attr.1 + } + } + + return highlightAttributesForSubtitle + } + + // Handle inline behaviour + func handleInlineFiltering() { + if let text = self.text { + if text == "" { + self.placeholderLabel?.attributedText = nil + } else { + if let firstResult = filteredResults.first { + self.placeholderLabel?.attributedText = firstResult.attributedTitle + } else { + self.placeholderLabel?.attributedText = nil + } + } + } + } + + // MARK: - Prepare for draw table result + + fileprivate func prepareDrawTableResult() { + guard let frame = self.superview?.convert(self.frame, to: UIApplication.shared.keyWindow) else { return } + if let keyboardFrame = keyboardFrame { + var newFrame = frame + newFrame.size.height += theme.cellHeight + + if keyboardFrame.intersects(newFrame) { + direction = .up + } else { + direction = .down + } + + redrawSearchTableView() + } else { + if self.center.y + theme.cellHeight > UIApplication.shared.keyWindow!.frame.size.height { + direction = .up + } else { + direction = .down + } + } + } +} + +extension SearchTextField: UITableViewDelegate, UITableViewDataSource { + public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + tableView.isHidden = !interactedWith || (filteredResults.count == 0) + shadowView?.isHidden = !interactedWith || (filteredResults.count == 0) + + if maxNumberOfResults > 0 { + return min(filteredResults.count, maxNumberOfResults) + } else { + return filteredResults.count + } + } + + public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + var cell = tableView.dequeueReusableCell(withIdentifier: SearchTextField.cellIdentifier) + + if cell == nil { + cell = UITableViewCell(style: .subtitle, reuseIdentifier: SearchTextField.cellIdentifier) + } + + cell!.backgroundColor = UIColor.clear + cell!.layoutMargins = UIEdgeInsets.zero + cell!.preservesSuperviewLayoutMargins = false + cell!.textLabel?.font = theme.font + cell!.detailTextLabel?.font = UIFont(name: theme.font.fontName, size: theme.font.pointSize * fontConversionRate) + cell!.textLabel?.textColor = theme.fontColor + cell!.detailTextLabel?.textColor = theme.subtitleFontColor + + cell!.textLabel?.text = filteredResults[(indexPath as NSIndexPath).row].title + cell!.detailTextLabel?.text = filteredResults[(indexPath as NSIndexPath).row].subtitle + cell!.textLabel?.attributedText = filteredResults[(indexPath as NSIndexPath).row].attributedTitle + cell!.detailTextLabel?.attributedText = filteredResults[(indexPath as NSIndexPath).row].attributedSubtitle + + cell!.imageView?.image = filteredResults[(indexPath as NSIndexPath).row].image + + cell!.selectionStyle = .none + + return cell! + } + + public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return theme.cellHeight + } + + public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + if itemSelectionHandler == nil { + self.text = filteredResults[(indexPath as NSIndexPath).row].title + } else { + let index = indexPath.row + itemSelectionHandler!(filteredResults, index) + } + + clearResults() + } +} + +//////////////////////////////////////////////////////////////////////// +// Search Text Field Theme + +public struct SearchTextFieldTheme { + public var cellHeight: CGFloat + public var bgColor: UIColor + public var borderColor: UIColor + public var borderWidth : CGFloat = 0 + public var separatorColor: UIColor + public var font: UIFont + public var fontColor: UIColor + public var subtitleFontColor: UIColor + public var placeholderColor: UIColor? + + init(cellHeight: CGFloat, bgColor:UIColor, borderColor: UIColor, separatorColor: UIColor, font: UIFont, fontColor: UIColor, subtitleFontColor: UIColor? = nil) { + self.cellHeight = cellHeight + self.borderColor = borderColor + self.separatorColor = separatorColor + self.bgColor = bgColor + self.font = font + self.fontColor = fontColor + self.subtitleFontColor = subtitleFontColor ?? fontColor + } + + public static func lightTheme() -> SearchTextFieldTheme { + return SearchTextFieldTheme(cellHeight: 30, bgColor: UIColor (red: 1, green: 1, blue: 1, alpha: 0.6), borderColor: UIColor (red: 0.9, green: 0.9, blue: 0.9, alpha: 1.0), separatorColor: UIColor.clear, font: UIFont.systemFont(ofSize: 10), fontColor: UIColor.black) + } + + public static func darkTheme() -> SearchTextFieldTheme { + return SearchTextFieldTheme(cellHeight: 30, bgColor: UIColor (red: 0.8, green: 0.8, blue: 0.8, alpha: 0.6), borderColor: UIColor (red: 0.7, green: 0.7, blue: 0.7, alpha: 1.0), separatorColor: UIColor.clear, font: UIFont.systemFont(ofSize: 10), fontColor: UIColor.white) + } +} + +//////////////////////////////////////////////////////////////////////// +// Filter Item + +open class SearchTextFieldItem { + // Private vars + fileprivate var attributedTitle: NSMutableAttributedString? + fileprivate var attributedSubtitle: NSMutableAttributedString? + + // Public interface + public var title: String + public var subtitle: String? + public var image: UIImage? + + public init(title: String, subtitle: String?, image: UIImage?) { + self.title = title + self.subtitle = subtitle + self.image = image + } + + public init(title: String, subtitle: String?) { + self.title = title + self.subtitle = subtitle + } + + public init(title: String) { + self.title = title + } +} + +public typealias SearchTextFieldItemHandler = (_ filteredResults: [SearchTextFieldItem], _ index: Int) -> Void + +//////////////////////////////////////////////////////////////////////// +// Suggestions List Direction + +enum Direction { + case down + case up +} diff --git a/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/Pods-SearchTextFieldWithRange/Pods-SearchTextFieldWithRange-acknowledgements.markdown b/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/Pods-SearchTextFieldWithRange/Pods-SearchTextFieldWithRange-acknowledgements.markdown new file mode 100644 index 0000000..1a32943 --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/Pods-SearchTextFieldWithRange/Pods-SearchTextFieldWithRange-acknowledgements.markdown @@ -0,0 +1,26 @@ +# Acknowledgements +This application makes use of the following third party libraries: + +## SearchTextField + +Copyright (c) 2016 Alejandro Pasccon + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +Generated by CocoaPods - https://cocoapods.org diff --git a/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/Pods-SearchTextFieldWithRange/Pods-SearchTextFieldWithRange-acknowledgements.plist b/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/Pods-SearchTextFieldWithRange/Pods-SearchTextFieldWithRange-acknowledgements.plist new file mode 100644 index 0000000..7134c9c --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/Pods-SearchTextFieldWithRange/Pods-SearchTextFieldWithRange-acknowledgements.plist @@ -0,0 +1,58 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + Type + PSGroupSpecifier + + + FooterText + Copyright (c) 2016 Alejandro Pasccon <apasccon@gmail.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + License + MIT + Title + SearchTextField + Type + PSGroupSpecifier + + + FooterText + Generated by CocoaPods - https://cocoapods.org + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/Pods-SearchTextFieldWithRange/Pods-SearchTextFieldWithRange-dummy.m b/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/Pods-SearchTextFieldWithRange/Pods-SearchTextFieldWithRange-dummy.m new file mode 100644 index 0000000..aca5726 --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/Pods-SearchTextFieldWithRange/Pods-SearchTextFieldWithRange-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_SearchTextFieldWithRange : NSObject +@end +@implementation PodsDummy_Pods_SearchTextFieldWithRange +@end diff --git a/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/Pods-SearchTextFieldWithRange/Pods-SearchTextFieldWithRange-umbrella.h b/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/Pods-SearchTextFieldWithRange/Pods-SearchTextFieldWithRange-umbrella.h new file mode 100644 index 0000000..bc5d60e --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/Pods-SearchTextFieldWithRange/Pods-SearchTextFieldWithRange-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double Pods_SearchTextFieldWithRangeVersionNumber; +FOUNDATION_EXPORT const unsigned char Pods_SearchTextFieldWithRangeVersionString[]; + diff --git a/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/Pods-SearchTextFieldWithRange/Pods-SearchTextFieldWithRange.debug.xcconfig b/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/Pods-SearchTextFieldWithRange/Pods-SearchTextFieldWithRange.debug.xcconfig new file mode 100644 index 0000000..636607b --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/Pods-SearchTextFieldWithRange/Pods-SearchTextFieldWithRange.debug.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SearchTextField" +OTHER_CFLAGS = $(inherited) -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/SearchTextField/SearchTextField.modulemap" +OTHER_LDFLAGS = $(inherited) -ObjC -l"SearchTextField" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS -Xcc -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/SearchTextField/SearchTextField.modulemap" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +SWIFT_INCLUDE_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SearchTextField" +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/Pods-SearchTextFieldWithRange/Pods-SearchTextFieldWithRange.modulemap b/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/Pods-SearchTextFieldWithRange/Pods-SearchTextFieldWithRange.modulemap new file mode 100644 index 0000000..8b920b8 --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/Pods-SearchTextFieldWithRange/Pods-SearchTextFieldWithRange.modulemap @@ -0,0 +1,6 @@ +module Pods_SearchTextFieldWithRange { + umbrella header "Pods-SearchTextFieldWithRange-umbrella.h" + + export * + module * { export * } +} diff --git a/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/Pods-SearchTextFieldWithRange/Pods-SearchTextFieldWithRange.release.xcconfig b/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/Pods-SearchTextFieldWithRange/Pods-SearchTextFieldWithRange.release.xcconfig new file mode 100644 index 0000000..636607b --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/Pods-SearchTextFieldWithRange/Pods-SearchTextFieldWithRange.release.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SearchTextField" +OTHER_CFLAGS = $(inherited) -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/SearchTextField/SearchTextField.modulemap" +OTHER_LDFLAGS = $(inherited) -ObjC -l"SearchTextField" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS -Xcc -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/SearchTextField/SearchTextField.modulemap" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +SWIFT_INCLUDE_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SearchTextField" +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/SearchTextField/SearchTextField-dummy.m b/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/SearchTextField/SearchTextField-dummy.m new file mode 100644 index 0000000..b56025a --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/SearchTextField/SearchTextField-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_SearchTextField : NSObject +@end +@implementation PodsDummy_SearchTextField +@end diff --git a/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/SearchTextField/SearchTextField-prefix.pch b/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/SearchTextField/SearchTextField-prefix.pch new file mode 100644 index 0000000..beb2a24 --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/SearchTextField/SearchTextField-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/SearchTextField/SearchTextField-umbrella.h b/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/SearchTextField/SearchTextField-umbrella.h new file mode 100644 index 0000000..7d3bf10 --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/SearchTextField/SearchTextField-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double SearchTextFieldVersionNumber; +FOUNDATION_EXPORT const unsigned char SearchTextFieldVersionString[]; + diff --git a/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/SearchTextField/SearchTextField.debug.xcconfig b/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/SearchTextField/SearchTextField.debug.xcconfig new file mode 100644 index 0000000..5aa4931 --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/SearchTextField/SearchTextField.debug.xcconfig @@ -0,0 +1,12 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SearchTextField +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS -import-underlying-module -Xcc -fmodule-map-file="${SRCROOT}/${MODULEMAP_FILE}" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/../../.. +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/SearchTextField/SearchTextField.modulemap b/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/SearchTextField/SearchTextField.modulemap new file mode 100644 index 0000000..5bb8a47 --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/SearchTextField/SearchTextField.modulemap @@ -0,0 +1,6 @@ +module SearchTextField { + umbrella header "SearchTextField-umbrella.h" + + export * + module * { export * } +} diff --git a/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/SearchTextField/SearchTextField.release.xcconfig b/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/SearchTextField/SearchTextField.release.xcconfig new file mode 100644 index 0000000..5aa4931 --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/Pods/Target Support Files/SearchTextField/SearchTextField.release.xcconfig @@ -0,0 +1,12 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SearchTextField +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS -import-underlying-module -Xcc -fmodule-map-file="${SRCROOT}/${MODULEMAP_FILE}" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/../../.. +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange.xcodeproj/project.pbxproj b/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange.xcodeproj/project.pbxproj new file mode 100644 index 0000000..9817426 --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange.xcodeproj/project.pbxproj @@ -0,0 +1,394 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 5D930663D5B62E31355CA52D /* libPods-SearchTextFieldWithRange.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D67D87013577DA89CF1AD3F /* libPods-SearchTextFieldWithRange.a */; }; + CED0AA71268310EC002C5DAF /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CED0AA70268310EC002C5DAF /* AppDelegate.swift */; }; + CED0AA75268310EC002C5DAF /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CED0AA74268310EC002C5DAF /* ViewController.swift */; }; + CED0AA78268310EC002C5DAF /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CED0AA76268310EC002C5DAF /* Main.storyboard */; }; + CED0AA7A268310EE002C5DAF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CED0AA79268310EE002C5DAF /* Assets.xcassets */; }; + CED0AA7D268310EE002C5DAF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CED0AA7B268310EE002C5DAF /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 3D67D87013577DA89CF1AD3F /* libPods-SearchTextFieldWithRange.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-SearchTextFieldWithRange.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B1B0B55D5E89AD187ABE144 /* Pods-SearchTextFieldWithRange.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SearchTextFieldWithRange.debug.xcconfig"; path = "Target Support Files/Pods-SearchTextFieldWithRange/Pods-SearchTextFieldWithRange.debug.xcconfig"; sourceTree = ""; }; + 80874CE3913485F3B1C94921 /* Pods-SearchTextFieldWithRange.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SearchTextFieldWithRange.release.xcconfig"; path = "Target Support Files/Pods-SearchTextFieldWithRange/Pods-SearchTextFieldWithRange.release.xcconfig"; sourceTree = ""; }; + CED0AA6D268310EC002C5DAF /* SearchTextFieldWithRange.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SearchTextFieldWithRange.app; sourceTree = BUILT_PRODUCTS_DIR; }; + CED0AA70268310EC002C5DAF /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + CED0AA74268310EC002C5DAF /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + CED0AA77268310EC002C5DAF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + CED0AA79268310EE002C5DAF /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + CED0AA7C268310EE002C5DAF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + CED0AA7E268310EE002C5DAF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + CED0AA6A268310EC002C5DAF /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 5D930663D5B62E31355CA52D /* libPods-SearchTextFieldWithRange.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1DC5F98BC0EB29BCF0C32DB3 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 3D67D87013577DA89CF1AD3F /* libPods-SearchTextFieldWithRange.a */, + ); + name = Frameworks; + sourceTree = ""; + }; + 42EB07426FC15B599984EAB6 /* Pods */ = { + isa = PBXGroup; + children = ( + 4B1B0B55D5E89AD187ABE144 /* Pods-SearchTextFieldWithRange.debug.xcconfig */, + 80874CE3913485F3B1C94921 /* Pods-SearchTextFieldWithRange.release.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; + CED0AA64268310EC002C5DAF = { + isa = PBXGroup; + children = ( + CED0AA6F268310EC002C5DAF /* SearchTextFieldWithRange */, + CED0AA6E268310EC002C5DAF /* Products */, + 42EB07426FC15B599984EAB6 /* Pods */, + 1DC5F98BC0EB29BCF0C32DB3 /* Frameworks */, + ); + sourceTree = ""; + }; + CED0AA6E268310EC002C5DAF /* Products */ = { + isa = PBXGroup; + children = ( + CED0AA6D268310EC002C5DAF /* SearchTextFieldWithRange.app */, + ); + name = Products; + sourceTree = ""; + }; + CED0AA6F268310EC002C5DAF /* SearchTextFieldWithRange */ = { + isa = PBXGroup; + children = ( + CED0AA70268310EC002C5DAF /* AppDelegate.swift */, + CED0AA74268310EC002C5DAF /* ViewController.swift */, + CED0AA76268310EC002C5DAF /* Main.storyboard */, + CED0AA79268310EE002C5DAF /* Assets.xcassets */, + CED0AA7B268310EE002C5DAF /* LaunchScreen.storyboard */, + CED0AA7E268310EE002C5DAF /* Info.plist */, + ); + path = SearchTextFieldWithRange; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + CED0AA6C268310EC002C5DAF /* SearchTextFieldWithRange */ = { + isa = PBXNativeTarget; + buildConfigurationList = CED0AA81268310EE002C5DAF /* Build configuration list for PBXNativeTarget "SearchTextFieldWithRange" */; + buildPhases = ( + 041F727A8253831D8320D2F9 /* [CP] Check Pods Manifest.lock */, + CED0AA69268310EC002C5DAF /* Sources */, + CED0AA6A268310EC002C5DAF /* Frameworks */, + CED0AA6B268310EC002C5DAF /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SearchTextFieldWithRange; + productName = SearchTextFieldWithRange; + productReference = CED0AA6D268310EC002C5DAF /* SearchTextFieldWithRange.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + CED0AA65268310EC002C5DAF /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1250; + LastUpgradeCheck = 1250; + TargetAttributes = { + CED0AA6C268310EC002C5DAF = { + CreatedOnToolsVersion = 12.5; + }; + }; + }; + buildConfigurationList = CED0AA68268310EC002C5DAF /* Build configuration list for PBXProject "SearchTextFieldWithRange" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = CED0AA64268310EC002C5DAF; + productRefGroup = CED0AA6E268310EC002C5DAF /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + CED0AA6C268310EC002C5DAF /* SearchTextFieldWithRange */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + CED0AA6B268310EC002C5DAF /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + CED0AA7D268310EE002C5DAF /* LaunchScreen.storyboard in Resources */, + CED0AA7A268310EE002C5DAF /* Assets.xcassets in Resources */, + CED0AA78268310EC002C5DAF /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 041F727A8253831D8320D2F9 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-SearchTextFieldWithRange-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + CED0AA69268310EC002C5DAF /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + CED0AA75268310EC002C5DAF /* ViewController.swift in Sources */, + CED0AA71268310EC002C5DAF /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + CED0AA76268310EC002C5DAF /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + CED0AA77268310EC002C5DAF /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + CED0AA7B268310EE002C5DAF /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + CED0AA7C268310EE002C5DAF /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + CED0AA7F268310EE002C5DAF /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + CED0AA80268310EE002C5DAF /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + CED0AA82268310EE002C5DAF /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4B1B0B55D5E89AD187ABE144 /* Pods-SearchTextFieldWithRange.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = ZNCGWW299S; + INFOPLIST_FILE = SearchTextFieldWithRange/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = ru.test.SearchTextFieldWithRange; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + CED0AA83268310EE002C5DAF /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 80874CE3913485F3B1C94921 /* Pods-SearchTextFieldWithRange.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = ZNCGWW299S; + INFOPLIST_FILE = SearchTextFieldWithRange/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = ru.test.SearchTextFieldWithRange; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + CED0AA68268310EC002C5DAF /* Build configuration list for PBXProject "SearchTextFieldWithRange" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + CED0AA7F268310EE002C5DAF /* Debug */, + CED0AA80268310EE002C5DAF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + CED0AA81268310EE002C5DAF /* Build configuration list for PBXNativeTarget "SearchTextFieldWithRange" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + CED0AA82268310EE002C5DAF /* Debug */, + CED0AA83268310EE002C5DAF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = CED0AA65268310EC002C5DAF /* Project object */; +} diff --git a/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange.xcworkspace/contents.xcworkspacedata b/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..ab44d0f --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange/AppDelegate.swift b/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange/AppDelegate.swift new file mode 100644 index 0000000..039cbb0 --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange/AppDelegate.swift @@ -0,0 +1,22 @@ +// +// AppDelegate.swift +// SearchTextFieldWithRange +// +// Created by Alexander Kormanovsky on 23.06.2021. +// + +import UIKit + +@main +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + +} + diff --git a/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange/Assets.xcassets/AccentColor.colorset/Contents.json b/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange/Assets.xcassets/AppIcon.appiconset/Contents.json b/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..9221b9b --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "60x60" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "60x60" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "83.5x83.5" + }, + { + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange/Assets.xcassets/Contents.json b/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange/Base.lproj/LaunchScreen.storyboard b/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange/Base.lproj/Main.storyboard b/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange/Base.lproj/Main.storyboard new file mode 100644 index 0000000..9d86e57 --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange/Base.lproj/Main.storyboard @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange/Info.plist b/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange/Info.plist new file mode 100644 index 0000000..1993c7f --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange/Info.plist @@ -0,0 +1,47 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSupportsIndirectInputEvents + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange/ViewController.swift b/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange/ViewController.swift new file mode 100644 index 0000000..f7c6ea2 --- /dev/null +++ b/Example - search range/SearchTextFieldWithRange/SearchTextFieldWithRange/ViewController.swift @@ -0,0 +1,86 @@ +// +// ViewController.swift +// SearchTextFieldWithRange +// +// Created by Alexander Kormanovsky on 23.06.2021. +// + +import UIKit +import SearchTextField + + +class ViewController: UIViewController { + + @IBOutlet var searchTextField: SearchTextField! + + override func viewDidLoad() { + super.viewDidLoad() + + setup() + } + + func setup() { + + var items = [SearchTextFieldItem]() + + for i in 0..<10 { + + // prepare title + + let attributedTitle = NSMutableAttributedString() + let searchableTitlePart = "\(i) Searchable title part" + let nonSearchableTitlePart = " Non-searchable" + + attributedTitle.append(NSAttributedString(string: searchableTitlePart, attributes: [.font : UIFont.systemFont(ofSize: 15), .foregroundColor : UIColor.green])) + attributedTitle.append(NSAttributedString(string: nonSearchableTitlePart, attributes: [.font : UIFont.systemFont(ofSize: 12), .foregroundColor : UIColor.gray])) + + let titleSearchRange = (attributedTitle.string as NSString).range(of: searchableTitlePart) + + // prepare subtitle + + let attributedSubtitle = NSMutableAttributedString() + let searchableSubtitlePart = "Searchable subtitle part" + let nonSearchableSubtitlePart = " Non-searchable" + + attributedSubtitle.append(NSAttributedString(string: searchableSubtitlePart, attributes: [.font : UIFont.systemFont(ofSize: 11), .foregroundColor : UIColor.green])) + attributedSubtitle.append(NSAttributedString(string: nonSearchableSubtitlePart, attributes: [.font : UIFont.systemFont(ofSize: 9), .foregroundColor : UIColor.gray])) + + let subtitleSearchRange = (attributedSubtitle.string as NSString).range(of: searchableSubtitlePart) + + let item = SearchTextFieldItem( + attributedTitle: attributedTitle, + attributedSubtitle: attributedSubtitle, + titleSearchRange: titleSearchRange, + subtitleSearchRange: subtitleSearchRange) + + items.append(item) + } + + searchTextField.filterItems(items) + + searchTextField.maxNumberOfResults = 10 + searchTextField.minCharactersNumberToStartFiltering = 2 + searchTextField.typingStoppedDelay = 0.4 + + searchTextField.theme.font = UIFont.systemFont(ofSize: 17) + searchTextField.theme.bgColor = .white + + searchTextField.itemSelectionHandler = { filteredResults, itemPosition in + let item = filteredResults[itemPosition] + // ... + } + + searchTextField.userStoppedTypingHandler = { + if let text = self.searchTextField.text, text.count >= self.searchTextField.minCharactersNumberToStartFiltering { + self.searchTextField.showLoadingIndicator() + + // ... + + self.searchTextField.stopLoadingIndicator() + } + } + + } + +} + diff --git a/SearchTextField/Classes/SearchTextField.swift b/SearchTextField/Classes/SearchTextField.swift index 9cf8f55..8d99ca6 100755 --- a/SearchTextField/Classes/SearchTextField.swift +++ b/SearchTextField/Classes/SearchTextField.swift @@ -445,17 +445,31 @@ open class SearchTextField: UITextField { if !inlineMode { // Find text in title and subtitle - let titleFilterRange = (item.title as NSString).range(of: text!, options: comparisonOptions) - let subtitleFilterRange = item.subtitle != nil ? (item.subtitle! as NSString).range(of: text!, options: comparisonOptions) : NSMakeRange(NSNotFound, 0) + var titleFilterRange = (item.title as NSString).range(of: text!, options: comparisonOptions) + + if let titleSearchRange = item.titleSearchRange { + if NSIntersectionRange(titleFilterRange, titleSearchRange).length == 0 { + titleFilterRange.location = NSNotFound + } + } + + var subtitleFilterRange = item.subtitle != nil ? (item.subtitle! as NSString).range(of: text!, options: comparisonOptions) : NSMakeRange(NSNotFound, 0) + + if let subtitleSearchRange = item.subtitleSearchRange { + if NSIntersectionRange(subtitleFilterRange, subtitleSearchRange).length == 0 { + subtitleFilterRange.location = NSNotFound + } + } if titleFilterRange.location != NSNotFound || subtitleFilterRange.location != NSNotFound || addAll { - item.attributedTitle = NSMutableAttributedString(string: item.title) - item.attributedSubtitle = NSMutableAttributedString(string: (item.subtitle != nil ? item.subtitle! : "")) - - item.attributedTitle!.setAttributes(highlightAttributes, range: titleFilterRange) + item.attributedTitle = (item.originalAttributedTitle?.mutableCopy() as? NSMutableAttributedString) ?? NSMutableAttributedString(string: item.title) + + item.attributedSubtitle = (item.originalAttributedSubtitle?.mutableCopy() as? NSMutableAttributedString) ?? NSMutableAttributedString(string: (item.subtitle != nil ? item.subtitle! : "")) + + item.attributedTitle!.addAttributes(highlightAttributes, range: titleFilterRange) if subtitleFilterRange.location != NSNotFound { - item.attributedSubtitle!.setAttributes(highlightAttributesForSubtitle(), range: subtitleFilterRange) + item.attributedSubtitle!.addAttributes(highlightAttributesForSubtitle(), range: subtitleFilterRange) } filteredResults.append(item) @@ -647,7 +661,12 @@ open class SearchTextFieldItem { // Private vars fileprivate var attributedTitle: NSMutableAttributedString? fileprivate var attributedSubtitle: NSMutableAttributedString? - + // use original* versions to restore attributed strings after adding highlighting attributes + fileprivate var originalAttributedTitle: NSMutableAttributedString? + fileprivate var originalAttributedSubtitle: NSMutableAttributedString? + fileprivate var titleSearchRange: NSRange? + fileprivate var subtitleSearchRange: NSRange? + // Public interface public var title: String public var subtitle: String? @@ -667,6 +686,18 @@ open class SearchTextFieldItem { public init(title: String) { self.title = title } + + public convenience init( + attributedTitle: NSAttributedString, + attributedSubtitle: NSAttributedString?, + titleSearchRange: NSRange? = nil, + subtitleSearchRange: NSRange? = nil) { + self.init(title: attributedTitle.string, subtitle: attributedSubtitle?.string) + self.originalAttributedTitle = (attributedTitle.mutableCopy() as! NSMutableAttributedString) + self.originalAttributedSubtitle = (attributedSubtitle?.mutableCopy() as! NSMutableAttributedString) + self.titleSearchRange = titleSearchRange + self.subtitleSearchRange = subtitleSearchRange + } } public typealias SearchTextFieldItemHandler = (_ filteredResults: [SearchTextFieldItem], _ index: Int) -> Void