diff --git a/QuickDialog.podspec b/QuickDialog.podspec index 8b17dcb9..bb910764 100644 --- a/QuickDialog.podspec +++ b/QuickDialog.podspec @@ -1,12 +1,12 @@ Pod::Spec.new do |s| s.name = 'QuickDialog' - s.version = '0.3' + s.version = '0.5' s.platform = :ios s.license = 'Apache License, Version 2.0' s.summary = 'Quick and easy dialog screens for iOS' - s.homepage = 'http://escoz.com/quickdialog-released/' + s.homepage = 'http://escoz.com/quickdialog' s.author = { 'Eduardo Scoz' => 'contact@escoz.com' } - s.source = { :git => 'git://github.com/escoz/QuickDialog.git', :tag => '0.3' } + s.source = { :git => 'git://github.com/escoz/QuickDialog.git', :tag => '0.5' } s.description = 'QuickDialog allows you to create HIG-compliant iOS forms for your apps without ' \ 'having to directly deal with UITableViews, delegates and data sources. Fast ' \ diff --git a/QuickDialog.xcodeproj/project.pbxproj b/QuickDialog.xcodeproj/project.pbxproj old mode 100644 new mode 100755 index 7928f86d..ea9e72dd --- a/QuickDialog.xcodeproj/project.pbxproj +++ b/QuickDialog.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + 194C3FC214EDF0510036C9E7 /* DOAutocompleteTextField.h in Headers */ = {isa = PBXBuildFile; fileRef = 194C3FC014EDF0510036C9E7 /* DOAutocompleteTextField.h */; }; + 194C3FC314EDF0510036C9E7 /* DOAutocompleteTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 194C3FC114EDF0510036C9E7 /* DOAutocompleteTextField.m */; }; 2C542394145ADEBD0026A152 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D80B0E3913E052DF00FA85CA /* Foundation.framework */; }; 2C54239F145ADF2B0026A152 /* QuickDialog.h in Headers */ = {isa = PBXBuildFile; fileRef = D8F180E813F0599A009B0C9E /* QuickDialog.h */; settings = {ATTRIBUTES = (); }; }; 2C5423A1145ADF2B0026A152 /* QDecimalTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D8F180E813F0599A009B0C9A /* QDecimalTableViewCell.m */; }; @@ -41,6 +43,8 @@ 2C5423DD145ADF2B0026A152 /* QWebElement.m in Sources */ = {isa = PBXBuildFile; fileRef = D811F8BD13EC905B00E3922B /* QWebElement.m */; }; 2C5423DF145ADF2B0026A152 /* QWebViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D811F8BF13EC905B00E3922B /* QWebViewController.m */; }; 2CE450B3145AE43D00B77D0E /* libQuickDialog.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2C542393145ADEBD0026A152 /* libQuickDialog.a */; }; + 2D1EC875167F911100262FA2 /* UIImageView+QuickDialogTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D1EC874167F911100262FA2 /* UIImageView+QuickDialogTableView.m */; }; + 2D1EC876167F963200262FA2 /* UIImageView+QuickDialogTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D1EC874167F911100262FA2 /* UIImageView+QuickDialogTableView.m */; }; B13B340614E450B9005EFB7F /* QValidator.h in Headers */ = {isa = PBXBuildFile; fileRef = B13B340414E450B8005EFB7F /* QValidator.h */; }; B13B340714E450B9005EFB7F /* QValidator.m in Sources */ = {isa = PBXBuildFile; fileRef = B13B340514E450B8005EFB7F /* QValidator.m */; }; B13B340B14E451EE005EFB7F /* QEntryValidator.h in Headers */ = {isa = PBXBuildFile; fileRef = B13B340914E451ED005EFB7F /* QEntryValidator.h */; }; @@ -94,7 +98,7 @@ D81F2EF214BBAFCE0066C372 /* QRadioItemElement.h in Headers */ = {isa = PBXBuildFile; fileRef = D811F8B013EC905B00E3922B /* QRadioItemElement.h */; settings = {ATTRIBUTES = (); }; }; D81F2EF314BBAFCE0066C372 /* QRadioSection.h in Headers */ = {isa = PBXBuildFile; fileRef = D811F8B213EC905B00E3922B /* QRadioSection.h */; settings = {ATTRIBUTES = (); }; }; D81F2EF414BBAFCE0066C372 /* QRootElement.h in Headers */ = {isa = PBXBuildFile; fileRef = D811F8B413EC905B00E3922B /* QRootElement.h */; settings = {ATTRIBUTES = (); }; }; - D81F2EF514BBAFCE0066C372 /* QRootElement+Builder.h in Headers */ = {isa = PBXBuildFile; fileRef = D871018414BB3D7A00156D9D /* QRootElement+Builder.h */; settings = {ATTRIBUTES = (); }; }; + D81F2EF514BBAFCE0066C372 /* QRootElement+JsonBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = D871018414BB3D7A00156D9D /* QRootElement+JsonBuilder.h */; settings = {ATTRIBUTES = (); }; }; D81F2EF614BBAFCE0066C372 /* QSection.h in Headers */ = {isa = PBXBuildFile; fileRef = D811F8B613EC905B00E3922B /* QSection.h */; settings = {ATTRIBUTES = (); }; }; D81F2EF714BBAFCE0066C372 /* QSortingSection.h in Headers */ = {isa = PBXBuildFile; fileRef = D811F8B813EC905B00E3922B /* QSortingSection.h */; settings = {ATTRIBUTES = (); }; }; D81F2EF814BBAFCE0066C372 /* QTextElement.h in Headers */ = {isa = PBXBuildFile; fileRef = D811F8BA13EC905B00E3922B /* QTextElement.h */; settings = {ATTRIBUTES = (); }; }; @@ -109,8 +113,22 @@ D86249FA14BB5AB5002F0585 /* jsondatasample.json in Resources */ = {isa = PBXBuildFile; fileRef = D86249F614BB5AB5002F0585 /* jsondatasample.json */; }; D86249FB14BB5AB5002F0585 /* loginform.json in Resources */ = {isa = PBXBuildFile; fileRef = D86249F714BB5AB5002F0585 /* loginform.json */; }; D86249FC14BB5AB5002F0585 /* sample.json in Resources */ = {isa = PBXBuildFile; fileRef = D86249F814BB5AB5002F0585 /* sample.json */; }; - D871018714BB3D7A00156D9D /* QRootElement+Builder.m in Sources */ = {isa = PBXBuildFile; fileRef = D871018514BB3D7A00156D9D /* QRootElement+Builder.m */; }; + D871018714BB3D7A00156D9D /* QRootElement+JsonBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = D871018514BB3D7A00156D9D /* QRootElement+JsonBuilder.m */; }; + D87B4FCB14F16197006DA833 /* QAutoEntryElement.h in Headers */ = {isa = PBXBuildFile; fileRef = D87B4FC514F16197006DA833 /* QAutoEntryElement.h */; }; + D87B4FCC14F16197006DA833 /* QAutoEntryElement.m in Sources */ = {isa = PBXBuildFile; fileRef = D87B4FC614F16197006DA833 /* QAutoEntryElement.m */; }; + D87B4FCD14F16197006DA833 /* QAutoEntryTableViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = D87B4FC714F16197006DA833 /* QAutoEntryTableViewCell.h */; }; + D87B4FCE14F16197006DA833 /* QAutoEntryTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D87B4FC814F16197006DA833 /* QAutoEntryTableViewCell.m */; }; + D894F38A15559D34000E3C0F /* NSMutableArray+IMSExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = D894F38815559D34000E3C0F /* NSMutableArray+IMSExtensions.h */; }; + D894F38B15559D34000E3C0F /* NSMutableArray+IMSExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = D894F38915559D34000E3C0F /* NSMutableArray+IMSExtensions.m */; }; D8A3DD87146045F000DE3528 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = D8A3DD86146045F000DE3528 /* Localizable.strings */; }; + D8B39450151394E1008ECB34 /* QEmptyListElement.h in Headers */ = {isa = PBXBuildFile; fileRef = D8B39449151394E1008ECB34 /* QEmptyListElement.h */; }; + D8B39451151394E1008ECB34 /* QEmptyListElement.m in Sources */ = {isa = PBXBuildFile; fileRef = D8B3944A151394E1008ECB34 /* QEmptyListElement.m */; }; + D8B39452151394E1008ECB34 /* QMultilineElement.h in Headers */ = {isa = PBXBuildFile; fileRef = D8B3944B151394E1008ECB34 /* QMultilineElement.h */; }; + D8B39453151394E1008ECB34 /* QMultilineElement.m in Sources */ = {isa = PBXBuildFile; fileRef = D8B3944C151394E1008ECB34 /* QMultilineElement.m */; }; + D8B39455151394E1008ECB34 /* QMultilineTextViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = D8B3944E151394E1008ECB34 /* QMultilineTextViewController.h */; }; + D8B39456151394E1008ECB34 /* QMultilineTextViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D8B3944F151394E1008ECB34 /* QMultilineTextViewController.m */; }; + D8B394691514E8B3008ECB34 /* QSegmentedElement.h in Headers */ = {isa = PBXBuildFile; fileRef = D8B394671514E8B3008ECB34 /* QSegmentedElement.h */; }; + D8B3946A1514E8B3008ECB34 /* QSegmentedElement.m in Sources */ = {isa = PBXBuildFile; fileRef = D8B394681514E8B3008ECB34 /* QSegmentedElement.m */; }; D8F180E713F0599A009B0C96 /* quickdialog.png in Resources */ = {isa = PBXBuildFile; fileRef = D8F180E513F0599A009B0C96 /* quickdialog.png */; }; D8F180E813F0599A009B0C96 /* quickdialog@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D8F180E613F0599A009B0C96 /* quickdialog@2x.png */; }; D8F180E813F0599A009B0CA8 /* QBadgeLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = D8F180E813F0599A009B0CA7 /* QBadgeLabel.m */; }; @@ -124,6 +142,27 @@ D8F180E813F0599A009B0CC2 /* QDynamicDataSection.h in Headers */ = {isa = PBXBuildFile; fileRef = D8F180E813F0599A009B0CC1 /* QDynamicDataSection.h */; }; D8F180E813F0599A009B0CC4 /* QTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D8F180E813F0599A009B0CC3 /* QTableViewCell.m */; }; D8F180E813F0599A009B0CC6 /* QTableViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = D8F180E813F0599A009B0CC5 /* QTableViewCell.h */; }; + D8F180E813F0599A009B0CC8 /* NSMutableArray+MoveObject.m in Sources */ = {isa = PBXBuildFile; fileRef = D8F180E813F0599A009B0CC7 /* NSMutableArray+MoveObject.m */; }; + D8F180E813F0599A009B0CCA /* NSMutableArray+MoveObject.h in Headers */ = {isa = PBXBuildFile; fileRef = D8F180E813F0599A009B0CC9 /* NSMutableArray+MoveObject.h */; }; + D8F180E813F0599A009B0CD0 /* jsonremote.json in Resources */ = {isa = PBXBuildFile; fileRef = D8F180E813F0599A009B0CCF /* jsonremote.json */; }; + D8F180E813F0599A009B0CD2 /* QuickDialogWebController.m in Sources */ = {isa = PBXBuildFile; fileRef = D8F180E813F0599A009B0CD1 /* QuickDialogWebController.m */; }; + D8F180E813F0599A009B0CD4 /* QuickDialogWebController.h in Headers */ = {isa = PBXBuildFile; fileRef = D8F180E813F0599A009B0CD3 /* QuickDialogWebController.h */; }; + F209CEE41536AB100043F61C /* PeriodPickerValueParser.m in Sources */ = {isa = PBXBuildFile; fileRef = F209CEE31536AB100043F61C /* PeriodPickerValueParser.m */; }; + F2304357156CDFDD006D0A56 /* QTextField.h in Headers */ = {isa = PBXBuildFile; fileRef = F2304355156CDFDD006D0A56 /* QTextField.h */; }; + F2304358156CDFDD006D0A56 /* QTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = F2304356156CDFDD006D0A56 /* QTextField.m */; }; + F2E6149E151C9E4D00F36976 /* QSelectSection.h in Headers */ = {isa = PBXBuildFile; fileRef = F2E6149C151C9E4D00F36976 /* QSelectSection.h */; }; + F2E6149F151C9E4D00F36976 /* QSelectSection.m in Sources */ = {isa = PBXBuildFile; fileRef = F2E6149D151C9E4D00F36976 /* QSelectSection.m */; }; + F2E614A2151CA1A100F36976 /* QSelectItemElement.h in Headers */ = {isa = PBXBuildFile; fileRef = F2E614A0151CA1A100F36976 /* QSelectItemElement.h */; }; + F2E614A3151CA1A100F36976 /* QSelectItemElement.m in Sources */ = {isa = PBXBuildFile; fileRef = F2E614A1151CA1A100F36976 /* QSelectItemElement.m */; }; + F2F23A20152DD48B00EB6685 /* QPickerElement.h in Headers */ = {isa = PBXBuildFile; fileRef = F2F23A19152DD48B00EB6685 /* QPickerElement.h */; }; + F2F23A21152DD48B00EB6685 /* QPickerElement.m in Sources */ = {isa = PBXBuildFile; fileRef = F2F23A1A152DD48B00EB6685 /* QPickerElement.m */; }; + F2F23A22152DD48B00EB6685 /* QPickerTableViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = F2F23A1B152DD48B00EB6685 /* QPickerTableViewCell.h */; }; + F2F23A23152DD48B00EB6685 /* QPickerTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = F2F23A1C152DD48B00EB6685 /* QPickerTableViewCell.m */; }; + F2F23A24152DD48B00EB6685 /* QPickerValueParser.h in Headers */ = {isa = PBXBuildFile; fileRef = F2F23A1D152DD48B00EB6685 /* QPickerValueParser.h */; }; + F2F23A25152DD48B00EB6685 /* QPickerTabDelimitedStringParser.h in Headers */ = {isa = PBXBuildFile; fileRef = F2F23A1E152DD48B00EB6685 /* QPickerTabDelimitedStringParser.h */; }; + F2F23A26152DD48B00EB6685 /* QPickerTabDelimitedStringParser.m in Sources */ = {isa = PBXBuildFile; fileRef = F2F23A1F152DD48B00EB6685 /* QPickerTabDelimitedStringParser.m */; }; + F2F23A26152DD48B00EB6687 /* QuickDialogController+Helpers.m in Sources */ = {isa = PBXBuildFile; fileRef = F2F23A26152DD48B00EB6686 /* QuickDialogController+Helpers.m */; }; + F2F23A26152DD48B00EB6689 /* QuickDialogController+Helpers.h in Headers */ = {isa = PBXBuildFile; fileRef = F2F23A26152DD48B00EB6688 /* QuickDialogController+Helpers.h */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -137,8 +176,12 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 194C3FC014EDF0510036C9E7 /* DOAutocompleteTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DOAutocompleteTextField.h; path = quickdialog/DOAutocompleteTextField.h; sourceTree = SOURCE_ROOT; }; + 194C3FC114EDF0510036C9E7 /* DOAutocompleteTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DOAutocompleteTextField.m; path = quickdialog/DOAutocompleteTextField.m; sourceTree = SOURCE_ROOT; }; 2C542393145ADEBD0026A152 /* libQuickDialog.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libQuickDialog.a; sourceTree = BUILT_PRODUCTS_DIR; }; 2CE450A9145ADFAC00B77D0E /* libQuickDialog-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "libQuickDialog-Prefix.pch"; path = "libQuickDialog/libQuickDialog-Prefix.pch"; sourceTree = SOURCE_ROOT; }; + 2D1EC873167F911100262FA2 /* UIImageView+QuickDialogTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIImageView+QuickDialogTableView.h"; path = "quickdialog/UIImageView+QuickDialogTableView.h"; sourceTree = SOURCE_ROOT; }; + 2D1EC874167F911100262FA2 /* UIImageView+QuickDialogTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIImageView+QuickDialogTableView.m"; path = "quickdialog/UIImageView+QuickDialogTableView.m"; sourceTree = SOURCE_ROOT; }; B13B340414E450B8005EFB7F /* QValidator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QValidator.h; path = quickdialog/QValidator.h; sourceTree = SOURCE_ROOT; }; B13B340514E450B8005EFB7F /* QValidator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = QValidator.m; path = quickdialog/QValidator.m; sourceTree = SOURCE_ROOT; }; B13B340914E451ED005EFB7F /* QEntryValidator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QEntryValidator.h; path = quickdialog/QEntryValidator.h; sourceTree = SOURCE_ROOT; }; @@ -241,9 +284,25 @@ D86249F614BB5AB5002F0585 /* jsondatasample.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = jsondatasample.json; path = sample/Resources/jsondatasample.json; sourceTree = SOURCE_ROOT; }; D86249F714BB5AB5002F0585 /* loginform.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = loginform.json; path = sample/Resources/loginform.json; sourceTree = SOURCE_ROOT; }; D86249F814BB5AB5002F0585 /* sample.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = sample.json; path = sample/Resources/sample.json; sourceTree = SOURCE_ROOT; }; - D871018414BB3D7A00156D9D /* QRootElement+Builder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "QRootElement+Builder.h"; path = "quickdialog/QRootElement+Builder.h"; sourceTree = SOURCE_ROOT; }; - D871018514BB3D7A00156D9D /* QRootElement+Builder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "QRootElement+Builder.m"; path = "quickdialog/QRootElement+Builder.m"; sourceTree = SOURCE_ROOT; }; + D871018414BB3D7A00156D9D /* QRootElement+JsonBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "QRootElement+JsonBuilder.h"; path = "quickdialog/QRootElement+JsonBuilder.h"; sourceTree = SOURCE_ROOT; }; + D871018514BB3D7A00156D9D /* QRootElement+JsonBuilder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "QRootElement+JsonBuilder.m"; path = "quickdialog/QRootElement+JsonBuilder.m"; sourceTree = SOURCE_ROOT; }; + D87B4FC314F16197006DA833 /* DOAutocompleteTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DOAutocompleteTextField.h; path = quickdialog/DOAutocompleteTextField.h; sourceTree = SOURCE_ROOT; }; + D87B4FC414F16197006DA833 /* DOAutocompleteTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DOAutocompleteTextField.m; path = quickdialog/DOAutocompleteTextField.m; sourceTree = SOURCE_ROOT; }; + D87B4FC514F16197006DA833 /* QAutoEntryElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QAutoEntryElement.h; path = quickdialog/QAutoEntryElement.h; sourceTree = SOURCE_ROOT; }; + D87B4FC614F16197006DA833 /* QAutoEntryElement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = QAutoEntryElement.m; path = quickdialog/QAutoEntryElement.m; sourceTree = SOURCE_ROOT; }; + D87B4FC714F16197006DA833 /* QAutoEntryTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QAutoEntryTableViewCell.h; path = quickdialog/QAutoEntryTableViewCell.h; sourceTree = SOURCE_ROOT; }; + D87B4FC814F16197006DA833 /* QAutoEntryTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = QAutoEntryTableViewCell.m; path = quickdialog/QAutoEntryTableViewCell.m; sourceTree = SOURCE_ROOT; }; + D894F38815559D34000E3C0F /* NSMutableArray+IMSExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSMutableArray+IMSExtensions.h"; path = "quickdialog/NSMutableArray+IMSExtensions.h"; sourceTree = SOURCE_ROOT; }; + D894F38915559D34000E3C0F /* NSMutableArray+IMSExtensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSMutableArray+IMSExtensions.m"; path = "quickdialog/NSMutableArray+IMSExtensions.m"; sourceTree = SOURCE_ROOT; }; D8A3DD86146045F000DE3528 /* Localizable.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = Localizable.strings; path = sample/Localizable.strings; sourceTree = SOURCE_ROOT; }; + D8B39449151394E1008ECB34 /* QEmptyListElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QEmptyListElement.h; path = quickdialog/QEmptyListElement.h; sourceTree = SOURCE_ROOT; }; + D8B3944A151394E1008ECB34 /* QEmptyListElement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = QEmptyListElement.m; path = quickdialog/QEmptyListElement.m; sourceTree = SOURCE_ROOT; }; + D8B3944B151394E1008ECB34 /* QMultilineElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QMultilineElement.h; path = quickdialog/QMultilineElement.h; sourceTree = SOURCE_ROOT; }; + D8B3944C151394E1008ECB34 /* QMultilineElement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = QMultilineElement.m; path = quickdialog/QMultilineElement.m; sourceTree = SOURCE_ROOT; }; + D8B3944E151394E1008ECB34 /* QMultilineTextViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QMultilineTextViewController.h; path = quickdialog/QMultilineTextViewController.h; sourceTree = SOURCE_ROOT; }; + D8B3944F151394E1008ECB34 /* QMultilineTextViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = QMultilineTextViewController.m; path = quickdialog/QMultilineTextViewController.m; sourceTree = SOURCE_ROOT; }; + D8B394671514E8B3008ECB34 /* QSegmentedElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QSegmentedElement.h; path = quickdialog/QSegmentedElement.h; sourceTree = SOURCE_ROOT; }; + D8B394681514E8B3008ECB34 /* QSegmentedElement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = QSegmentedElement.m; path = quickdialog/QSegmentedElement.m; sourceTree = SOURCE_ROOT; }; D8F180E513F0599A009B0C96 /* quickdialog.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = quickdialog.png; sourceTree = ""; }; D8F180E613F0599A009B0C96 /* quickdialog@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "quickdialog@2x.png"; sourceTree = ""; }; D8F180E813F0599A009B0C97 /* QDecimalElement.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = QDecimalElement.m; path = quickdialog/QDecimalElement.m; sourceTree = SOURCE_ROOT; }; @@ -266,6 +325,28 @@ D8F180E813F0599A009B0CC1 /* QDynamicDataSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QDynamicDataSection.h; path = quickdialog/QDynamicDataSection.h; sourceTree = SOURCE_ROOT; }; D8F180E813F0599A009B0CC3 /* QTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = QTableViewCell.m; path = quickdialog/QTableViewCell.m; sourceTree = SOURCE_ROOT; }; D8F180E813F0599A009B0CC5 /* QTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QTableViewCell.h; path = quickdialog/QTableViewCell.h; sourceTree = SOURCE_ROOT; }; + D8F180E813F0599A009B0CC7 /* NSMutableArray+MoveObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSMutableArray+MoveObject.m"; path = "quickdialog/NSMutableArray+MoveObject.m"; sourceTree = SOURCE_ROOT; }; + D8F180E813F0599A009B0CC9 /* NSMutableArray+MoveObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSMutableArray+MoveObject.h"; path = "quickdialog/NSMutableArray+MoveObject.h"; sourceTree = SOURCE_ROOT; }; + D8F180E813F0599A009B0CCF /* jsonremote.json */ = {isa = PBXFileReference; lastKnownFileType = file.json; name = jsonremote.json; path = sample/Resources/jsonremote.json; sourceTree = SOURCE_ROOT; }; + D8F180E813F0599A009B0CD1 /* QuickDialogWebController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = QuickDialogWebController.m; path = quickdialog/QuickDialogWebController.m; sourceTree = SOURCE_ROOT; }; + D8F180E813F0599A009B0CD3 /* QuickDialogWebController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QuickDialogWebController.h; path = quickdialog/QuickDialogWebController.h; sourceTree = SOURCE_ROOT; }; + F209CEE21536AB100043F61C /* PeriodPickerValueParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PeriodPickerValueParser.h; path = sample/PeriodPickerValueParser.h; sourceTree = SOURCE_ROOT; }; + F209CEE31536AB100043F61C /* PeriodPickerValueParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PeriodPickerValueParser.m; path = sample/PeriodPickerValueParser.m; sourceTree = SOURCE_ROOT; }; + F2304355156CDFDD006D0A56 /* QTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QTextField.h; path = quickdialog/QTextField.h; sourceTree = SOURCE_ROOT; }; + F2304356156CDFDD006D0A56 /* QTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = QTextField.m; path = quickdialog/QTextField.m; sourceTree = SOURCE_ROOT; }; + F2E6149C151C9E4D00F36976 /* QSelectSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QSelectSection.h; path = quickdialog/QSelectSection.h; sourceTree = SOURCE_ROOT; }; + F2E6149D151C9E4D00F36976 /* QSelectSection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = QSelectSection.m; path = quickdialog/QSelectSection.m; sourceTree = SOURCE_ROOT; }; + F2E614A0151CA1A100F36976 /* QSelectItemElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QSelectItemElement.h; path = quickdialog/QSelectItemElement.h; sourceTree = SOURCE_ROOT; }; + F2E614A1151CA1A100F36976 /* QSelectItemElement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = QSelectItemElement.m; path = quickdialog/QSelectItemElement.m; sourceTree = SOURCE_ROOT; }; + F2F23A19152DD48B00EB6685 /* QPickerElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QPickerElement.h; path = quickdialog/QPickerElement.h; sourceTree = SOURCE_ROOT; }; + F2F23A1A152DD48B00EB6685 /* QPickerElement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = QPickerElement.m; path = quickdialog/QPickerElement.m; sourceTree = SOURCE_ROOT; }; + F2F23A1B152DD48B00EB6685 /* QPickerTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QPickerTableViewCell.h; path = quickdialog/QPickerTableViewCell.h; sourceTree = SOURCE_ROOT; }; + F2F23A1C152DD48B00EB6685 /* QPickerTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = QPickerTableViewCell.m; path = quickdialog/QPickerTableViewCell.m; sourceTree = SOURCE_ROOT; }; + F2F23A1D152DD48B00EB6685 /* QPickerValueParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QPickerValueParser.h; path = quickdialog/QPickerValueParser.h; sourceTree = SOURCE_ROOT; }; + F2F23A1E152DD48B00EB6685 /* QPickerTabDelimitedStringParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QPickerTabDelimitedStringParser.h; path = quickdialog/QPickerTabDelimitedStringParser.h; sourceTree = SOURCE_ROOT; }; + F2F23A1F152DD48B00EB6685 /* QPickerTabDelimitedStringParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = QPickerTabDelimitedStringParser.m; path = quickdialog/QPickerTabDelimitedStringParser.m; sourceTree = SOURCE_ROOT; }; + F2F23A26152DD48B00EB6686 /* QuickDialogController+Helpers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "QuickDialogController+Helpers.m"; path = "quickdialog/QuickDialogController+Helpers.m"; sourceTree = SOURCE_ROOT; }; + F2F23A26152DD48B00EB6688 /* QuickDialogController+Helpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "QuickDialogController+Helpers.h"; path = "quickdialog/QuickDialogController+Helpers.h"; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -353,6 +434,8 @@ D811F8EC13EC907200E3922B /* ExampleAppDelegate.m */, D811F8ED13EC907200E3922B /* ExampleViewController.h */, D811F8EE13EC907200E3922B /* ExampleViewController.m */, + F209CEE21536AB100043F61C /* PeriodPickerValueParser.h */, + F209CEE31536AB100043F61C /* PeriodPickerValueParser.m */, D811F8EF13EC907200E3922B /* Resources */, D80B0E3E13E052DF00FA85CA /* Supporting Files */, ); @@ -405,6 +488,31 @@ D860356713E0534000CB1785 /* quickdialog */ = { isa = PBXGroup; children = ( + F2F23A12152DD45100EB6685 /* QPickerElement */, + 2D1EC873167F911100262FA2 /* UIImageView+QuickDialogTableView.h */, + 2D1EC874167F911100262FA2 /* UIImageView+QuickDialogTableView.m */, + D894F38815559D34000E3C0F /* NSMutableArray+IMSExtensions.h */, + D894F38915559D34000E3C0F /* NSMutableArray+IMSExtensions.m */, + F2F23A26152DD48B00EB6688 /* QuickDialogController+Helpers.h */, + F2F23A26152DD48B00EB6686 /* QuickDialogController+Helpers.m */, + D8F180E813F0599A009B0CD3 /* QuickDialogWebController.h */, + D8F180E813F0599A009B0CD1 /* QuickDialogWebController.m */, + D8B394681514E8B3008ECB34 /* QSegmentedElement.m */, + D8B394671514E8B3008ECB34 /* QSegmentedElement.h */, + D8B39449151394E1008ECB34 /* QEmptyListElement.h */, + D8B3944A151394E1008ECB34 /* QEmptyListElement.m */, + D8B3944B151394E1008ECB34 /* QMultilineElement.h */, + D8B3944C151394E1008ECB34 /* QMultilineElement.m */, + D8B3944E151394E1008ECB34 /* QMultilineTextViewController.h */, + D8B3944F151394E1008ECB34 /* QMultilineTextViewController.m */, + D8F180E813F0599A009B0CC9 /* NSMutableArray+MoveObject.h */, + D8F180E813F0599A009B0CC7 /* NSMutableArray+MoveObject.m */, + D87B4FC314F16197006DA833 /* DOAutocompleteTextField.h */, + D87B4FC414F16197006DA833 /* DOAutocompleteTextField.m */, + D87B4FC514F16197006DA833 /* QAutoEntryElement.h */, + D87B4FC614F16197006DA833 /* QAutoEntryElement.m */, + D87B4FC714F16197006DA833 /* QAutoEntryTableViewCell.h */, + D87B4FC814F16197006DA833 /* QAutoEntryTableViewCell.m */, D8F180E813F0599A009B0CC5 /* QTableViewCell.h */, D8F180E813F0599A009B0CC3 /* QTableViewCell.m */, D8F180E813F0599A009B0CC1 /* QDynamicDataSection.h */, @@ -439,6 +547,8 @@ D811F89113EC905B00E3922B /* QDateTimeInlineElement.m */, D811F89213EC905B00E3922B /* QElement.h */, D811F89313EC905B00E3922B /* QElement.m */, + F2304355156CDFDD006D0A56 /* QTextField.h */, + F2304356156CDFDD006D0A56 /* QTextField.m */, D811F89413EC905B00E3922B /* QEntryElement.h */, D811F89513EC905B00E3922B /* QEntryElement.m */, D811F89613EC905B00E3922B /* QEntryTableViewCell.h */, @@ -471,10 +581,14 @@ D811F8B113EC905B00E3922B /* QRadioItemElement.m */, D811F8B213EC905B00E3922B /* QRadioSection.h */, D811F8B313EC905B00E3922B /* QRadioSection.m */, + F2E6149C151C9E4D00F36976 /* QSelectSection.h */, + F2E6149D151C9E4D00F36976 /* QSelectSection.m */, + F2E614A0151CA1A100F36976 /* QSelectItemElement.h */, + F2E614A1151CA1A100F36976 /* QSelectItemElement.m */, D811F8B413EC905B00E3922B /* QRootElement.h */, D811F8B513EC905B00E3922B /* QRootElement.m */, - D871018414BB3D7A00156D9D /* QRootElement+Builder.h */, - D871018514BB3D7A00156D9D /* QRootElement+Builder.m */, + D871018414BB3D7A00156D9D /* QRootElement+JsonBuilder.h */, + D871018514BB3D7A00156D9D /* QRootElement+JsonBuilder.m */, D811F8B613EC905B00E3922B /* QSection.h */, D811F8B713EC905B00E3922B /* QSection.m */, D811F8B813EC905B00E3922B /* QSortingSection.h */, @@ -489,6 +603,8 @@ B13B340514E450B8005EFB7F /* QValidator.m */, B13B340914E451ED005EFB7F /* QEntryValidator.h */, B13B340A14E451EE005EFB7F /* QEntryValidator.m */, + 194C3FC014EDF0510036C9E7 /* DOAutocompleteTextField.h */, + 194C3FC114EDF0510036C9E7 /* DOAutocompleteTextField.m */, ); name = quickdialog; path = quickform; @@ -497,6 +613,7 @@ D86249F014BB5A64002F0585 /* json */ = { isa = PBXGroup; children = ( + D8F180E813F0599A009B0CCF /* jsonremote.json */, D86249F514BB5AB5002F0585 /* jsonadvancedsample.json */, D86249F614BB5AB5002F0585 /* jsondatasample.json */, D86249F714BB5AB5002F0585 /* loginform.json */, @@ -505,6 +622,20 @@ name = json; sourceTree = ""; }; + F2F23A12152DD45100EB6685 /* QPickerElement */ = { + isa = PBXGroup; + children = ( + F2F23A19152DD48B00EB6685 /* QPickerElement.h */, + F2F23A1A152DD48B00EB6685 /* QPickerElement.m */, + F2F23A1B152DD48B00EB6685 /* QPickerTableViewCell.h */, + F2F23A1C152DD48B00EB6685 /* QPickerTableViewCell.m */, + F2F23A1D152DD48B00EB6685 /* QPickerValueParser.h */, + F2F23A1E152DD48B00EB6685 /* QPickerTabDelimitedStringParser.h */, + F2F23A1F152DD48B00EB6685 /* QPickerTabDelimitedStringParser.m */, + ); + name = QPickerElement; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -513,8 +644,10 @@ buildActionMask = 2147483647; files = ( 2C54239F145ADF2B0026A152 /* QuickDialog.h in Headers */, + D8F180E813F0599A009B0CCA /* NSMutableArray+MoveObject.h in Headers */, D81F2ED714BBAFCE0066C372 /* QRootBuilder.h in Headers */, D81F2ED814BBAFCE0066C372 /* QBindingEvaluator.h in Headers */, + D81F2EE714BBAFCE0066C372 /* QLabelElement.h in Headers */, D81F2ED914BBAFCE0066C372 /* QBadgeLabel.h in Headers */, D81F2EDA14BBAFCE0066C372 /* QDecimalTableViewCell.h in Headers */, D81F2EDB14BBAFCE0066C372 /* QDecimalElement.h in Headers */, @@ -529,7 +662,6 @@ D81F2EE414BBAFCE0066C372 /* QEntryElement.h in Headers */, D81F2EE514BBAFCE0066C372 /* QEntryTableViewCell.h in Headers */, D81F2EE614BBAFCE0066C372 /* QFloatElement.h in Headers */, - D81F2EE714BBAFCE0066C372 /* QLabelElement.h in Headers */, D81F2EE814BBAFCE0066C372 /* QMapElement.h in Headers */, D81F2EE914BBAFCE0066C372 /* QMapViewController.h in Headers */, D81F2EEA14BBAFCE0066C372 /* QMapAnnotation.h in Headers */, @@ -543,7 +675,7 @@ D81F2EF214BBAFCE0066C372 /* QRadioItemElement.h in Headers */, D81F2EF314BBAFCE0066C372 /* QRadioSection.h in Headers */, D81F2EF414BBAFCE0066C372 /* QRootElement.h in Headers */, - D81F2EF514BBAFCE0066C372 /* QRootElement+Builder.h in Headers */, + D81F2EF514BBAFCE0066C372 /* QRootElement+JsonBuilder.h in Headers */, D81F2EF614BBAFCE0066C372 /* QSection.h in Headers */, D81F2EF714BBAFCE0066C372 /* QSortingSection.h in Headers */, D81F2EF814BBAFCE0066C372 /* QTextElement.h in Headers */, @@ -555,6 +687,23 @@ D8F180E813F0599A009B0CC6 /* QTableViewCell.h in Headers */, B13B340614E450B9005EFB7F /* QValidator.h in Headers */, B13B340B14E451EE005EFB7F /* QEntryValidator.h in Headers */, + 194C3FC214EDF0510036C9E7 /* DOAutocompleteTextField.h in Headers */, + D87B4FCB14F16197006DA833 /* QAutoEntryElement.h in Headers */, + D87B4FCD14F16197006DA833 /* QAutoEntryTableViewCell.h in Headers */, + D8B39450151394E1008ECB34 /* QEmptyListElement.h in Headers */, + D8B39452151394E1008ECB34 /* QMultilineElement.h in Headers */, + D8B39455151394E1008ECB34 /* QMultilineTextViewController.h in Headers */, + D8B394691514E8B3008ECB34 /* QSegmentedElement.h in Headers */, + D8F180E813F0599A009B0CD4 /* QuickDialogWebController.h in Headers */, + F2E6149E151C9E4D00F36976 /* QSelectSection.h in Headers */, + F2E614A2151CA1A100F36976 /* QSelectItemElement.h in Headers */, + F2F23A20152DD48B00EB6685 /* QPickerElement.h in Headers */, + F2F23A22152DD48B00EB6685 /* QPickerTableViewCell.h in Headers */, + F2F23A24152DD48B00EB6685 /* QPickerValueParser.h in Headers */, + F2F23A25152DD48B00EB6685 /* QPickerTabDelimitedStringParser.h in Headers */, + F2F23A26152DD48B00EB6689 /* QuickDialogController+Helpers.h in Headers */, + D894F38A15559D34000E3C0F /* NSMutableArray+IMSExtensions.h in Headers */, + F2304357156CDFDD006D0A56 /* QTextField.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -602,7 +751,7 @@ D80B0E2A13E052DF00FA85CA /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0420; + LastUpgradeCheck = 0430; }; buildConfigurationList = D80B0E2D13E052DF00FA85CA /* Build configuration list for PBXProject "QuickDialog" */; compatibilityVersion = "Xcode 3.2"; @@ -646,6 +795,7 @@ D86249FA14BB5AB5002F0585 /* jsondatasample.json in Resources */, D86249FB14BB5AB5002F0585 /* loginform.json in Resources */, D86249FC14BB5AB5002F0585 /* sample.json in Resources */, + D8F180E813F0599A009B0CD0 /* jsonremote.json in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -656,6 +806,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 2D1EC876167F963200262FA2 /* UIImageView+QuickDialogTableView.m in Sources */, 2C5423A1145ADF2B0026A152 /* QDecimalTableViewCell.m in Sources */, 2C5423A3145ADF2B0026A152 /* QDecimalElement.m in Sources */, 2C5423A5145ADF2B0026A152 /* QBadgeElement.m in Sources */, @@ -665,11 +816,11 @@ 2C5423AD145ADF2B0026A152 /* QDateEntryTableViewCell.m in Sources */, 2C5423AF145ADF2B0026A152 /* QDateTimeElement.m in Sources */, 2C5423B1145ADF2B0026A152 /* QDateTimeInlineElement.m in Sources */, + 2C5423BB145ADF2B0026A152 /* QLabelElement.m in Sources */, 2C5423B3145ADF2B0026A152 /* QElement.m in Sources */, 2C5423B5145ADF2B0026A152 /* QEntryElement.m in Sources */, 2C5423B7145ADF2B0026A152 /* QEntryTableViewCell.m in Sources */, 2C5423B9145ADF2B0026A152 /* QFloatElement.m in Sources */, - 2C5423BB145ADF2B0026A152 /* QLabelElement.m in Sources */, 2C5423BD145ADF2B0026A152 /* QMapElement.m in Sources */, 2C5423BF145ADF2B0026A152 /* QMapViewController.m in Sources */, 2C5423C1145ADF2B0026A152 /* QMapAnnotation.m in Sources */, @@ -689,13 +840,30 @@ 2C5423DF145ADF2B0026A152 /* QWebViewController.m in Sources */, D8F180E813F0599A009B0CA8 /* QBadgeLabel.m in Sources */, D8F180E813F0599A009B0CB3 /* QBindingEvaluator.m in Sources */, - D871018714BB3D7A00156D9D /* QRootElement+Builder.m in Sources */, + D871018714BB3D7A00156D9D /* QRootElement+JsonBuilder.m in Sources */, D8F180E813F0599A009B0CB7 /* QRootBuilder.m in Sources */, D8F180E813F0599A009B0CBC /* QLoadingElement.m in Sources */, D8F180E813F0599A009B0CC0 /* QDynamicDataSection.m in Sources */, D8F180E813F0599A009B0CC4 /* QTableViewCell.m in Sources */, B13B340714E450B9005EFB7F /* QValidator.m in Sources */, B13B340C14E451EE005EFB7F /* QEntryValidator.m in Sources */, + 194C3FC314EDF0510036C9E7 /* DOAutocompleteTextField.m in Sources */, + D87B4FCC14F16197006DA833 /* QAutoEntryElement.m in Sources */, + D87B4FCE14F16197006DA833 /* QAutoEntryTableViewCell.m in Sources */, + D8F180E813F0599A009B0CC8 /* NSMutableArray+MoveObject.m in Sources */, + D8B39451151394E1008ECB34 /* QEmptyListElement.m in Sources */, + D8B39453151394E1008ECB34 /* QMultilineElement.m in Sources */, + D8B39456151394E1008ECB34 /* QMultilineTextViewController.m in Sources */, + D8B3946A1514E8B3008ECB34 /* QSegmentedElement.m in Sources */, + D8F180E813F0599A009B0CD2 /* QuickDialogWebController.m in Sources */, + F2E6149F151C9E4D00F36976 /* QSelectSection.m in Sources */, + F2E614A3151CA1A100F36976 /* QSelectItemElement.m in Sources */, + F2F23A21152DD48B00EB6685 /* QPickerElement.m in Sources */, + F2F23A23152DD48B00EB6685 /* QPickerTableViewCell.m in Sources */, + F2F23A26152DD48B00EB6685 /* QPickerTabDelimitedStringParser.m in Sources */, + F2F23A26152DD48B00EB6687 /* QuickDialogController+Helpers.m in Sources */, + D894F38B15559D34000E3C0F /* NSMutableArray+IMSExtensions.m in Sources */, + F2304358156CDFDD006D0A56 /* QTextField.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -711,6 +879,8 @@ D811F90213EC907200E3922B /* ExampleAppDelegate.m in Sources */, D811F90313EC907200E3922B /* ExampleViewController.m in Sources */, D8F180E813F0599A009B0CAC /* JsonDataSampleController.m in Sources */, + F209CEE41536AB100043F61C /* PeriodPickerValueParser.m in Sources */, + 2D1EC875167F911100262FA2 /* UIImageView+QuickDialogTableView.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -746,6 +916,7 @@ DSTROOT = /tmp/libQuickDialog.dst; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "libQuickDialog/libQuickDialog-Prefix.pch"; + GCC_THUMB_SUPPORT = NO; OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = "$(TARGET_NAME)"; PUBLIC_HEADERS_FOLDER_PATH = /include/QuickDialog; @@ -763,6 +934,7 @@ DSTROOT = /tmp/libQuickDialog.dst; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "libQuickDialog/libQuickDialog-Prefix.pch"; + GCC_THUMB_SUPPORT = NO; OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = "$(TARGET_NAME)"; PUBLIC_HEADERS_FOLDER_PATH = /include/QuickDialog; diff --git a/QuickDialog.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/QuickDialog.xcodeproj/project.xcworkspace/contents.xcworkspacedata old mode 100644 new mode 100755 diff --git a/README.markdown b/README.markdown index 00f1727b..51fb4ae9 100644 --- a/README.markdown +++ b/README.markdown @@ -13,6 +13,9 @@ QuickDialog allows you to create HIG-compliant iOS forms for your apps without Download the project and run the demo app, I'm sure you'll like how simple it is to create powerful dialogs! +Have a question? ask it on our new Google Groups: https://groups.google.com/forum/?fromgroups&hl=en#!forum/quickdialog + + ---------- *QuickDialog is inspired by the brilliant MonoTouch.Dialog library created by Miguel de Icaza, which can be found at https://github.com/migueldeicaza/MonoTouch.Dialog.* diff --git a/quickdialog/DOAutocompleteTextField.h b/quickdialog/DOAutocompleteTextField.h new file mode 100644 index 00000000..03295cbb --- /dev/null +++ b/quickdialog/DOAutocompleteTextField.h @@ -0,0 +1,57 @@ +/* + * Copyright 2011 DoAT. All rights reserved. + * + * Updated by Iain Stubbs 2012 for use in QAutoEntryElement + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY DoAT “AS IS” WITHOUT ANY WARRANTIES WHATSOEVER. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF NON INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL DoAT OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of + * the authors and should not be interpreted as representing official policies, + * either expressed or implied, of DoAT. + */ + +#import + +@class DOAutocompleteTextField; + +@protocol DOAutocompleteTextFieldDelegate + +@optional +- (NSString*)textField:(DOAutocompleteTextField*)textField completionForPrefix:(NSString*)prefix; + +@end + +@interface DOAutocompleteTextField : UITextField +{ + UILabel *_autocompleteLabel; + NSString *_autoCompleteString; + NSArray *_autoCompletes; +} + +- (CGRect)autocompleteRectForBounds:(CGRect)bounds; +- (void)setAutocompleteTextColor:(UIColor*)color; +- (UIColor*)autocompleteTextColor; +- (NSString*)getAutoCompleteText; +- (void)setAutoCompletes:(NSArray*)autoCompletes; +- (NSArray*)getAutoCompletes; + +@end \ No newline at end of file diff --git a/quickdialog/DOAutocompleteTextField.m b/quickdialog/DOAutocompleteTextField.m new file mode 100644 index 00000000..80b5e05c --- /dev/null +++ b/quickdialog/DOAutocompleteTextField.m @@ -0,0 +1,169 @@ +/* + * Copyright 2011 DoAT. All rights reserved. + * + * Updated by Iain Stubbs 2012 for use in QAutoEntryElement + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY DoAT “AS IS” WITHOUT ANY WARRANTIES WHATSOEVER. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF NON INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL DoAT OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of + * the authors and should not be interpreted as representing official policies, + * either expressed or implied, of DoAT. + */ + +#import "DOAutocompleteTextField.h" +#import "NSMutableArray+IMSExtensions.h" + +@interface DOAutocompleteTextField (Private) + +- (void)setupSubviews; +- (void)_textDidChange:(NSNotification*)notification; +- (void)_updateAutocompleteLabel; + +@end + +@implementation DOAutocompleteTextField + +- (id)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) + { + [self setupSubviews]; + } + + return self; +} + +- (void)awakeFromNib +{ + [self setupSubviews]; +} + +- (void)setupSubviews +{ + _autocompleteLabel = [[UILabel alloc] initWithFrame:CGRectZero]; + _autocompleteLabel.font = self.font; + _autocompleteLabel.backgroundColor = [UIColor clearColor]; + _autocompleteLabel.textColor = [UIColor lightGrayColor]; + _autocompleteLabel.lineBreakMode = UILineBreakModeClip; + [self addSubview:_autocompleteLabel]; + [self bringSubviewToFront:_autocompleteLabel]; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_textDidChange:) name:UITextFieldTextDidChangeNotification object:self]; +} + +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotification object:self]; +} + +- (BOOL)becomeFirstResponder +{ + if ([self clearsOnBeginEditing]) + { + _autocompleteLabel.text = @""; + } + + _autocompleteLabel.hidden = NO; + return [super becomeFirstResponder]; +} + +- (BOOL)resignFirstResponder +{ + _autocompleteLabel.hidden = YES; + return [super resignFirstResponder]; +} + +- (void)setFont:(UIFont *)font +{ + [super setFont:font]; + [_autocompleteLabel setFont:font]; +} + +- (CGRect)autocompleteRectForBounds:(CGRect)bounds +{ + CGRect returnRect = CGRectZero; + CGRect textRect = [self textRectForBounds:self.bounds]; + // NSLog(@"textRect: %@", NSStringFromCGRect(textRect)); + + CGSize prefixTextSize = [self.text sizeWithFont:self.font + constrainedToSize:textRect.size + lineBreakMode:UILineBreakModeCharacterWrap]; + // NSLog(@"prefixTextSize: %@", NSStringFromCGSize(prefixTextSize)); + + CGSize autocompleteTextSize = [_autoCompleteString sizeWithFont:self.font + constrainedToSize:CGSizeMake(textRect.size.width-prefixTextSize.width, textRect.size.height) + lineBreakMode:UILineBreakModeCharacterWrap]; + + // NSLog(@"autocompleteTextSize: %@", NSStringFromCGSize(autocompleteTextSize)); + + returnRect = CGRectMake(textRect.origin.x + prefixTextSize.width, + textRect.origin.y,//+.5, + autocompleteTextSize.width, + textRect.size.height); + + return returnRect; +} + +- (void)setAutocompleteTextColor:(UIColor*)color +{ + _autocompleteLabel.textColor = color; +} + +- (UIColor*)autocompleteTextColor +{ + return _autocompleteLabel.textColor; +} + +- (void)_textDidChange:(NSNotification*)notification +{ + if ([((id)self.delegate) respondsToSelector:@selector(textField:completionForPrefix:)] ) + { + _autoCompleteString = [((id)self.delegate) textField:self completionForPrefix:self.text]; + [self _updateAutocompleteLabel]; + } +} + +- (void)_updateAutocompleteLabel +{ + [_autocompleteLabel setText:_autoCompleteString]; + [_autocompleteLabel sizeToFit]; + [_autocompleteLabel setFrame: [self autocompleteRectForBounds:self.bounds]]; +} + +- (NSString*)getAutoCompleteText +{ + NSMutableArray *ac = [NSMutableArray arrayWithObjects:self.text,_autoCompleteString, nil]; + return [ac concatStrings]; +} + +- (void)setAutoCompletes:(NSArray*)autoCompletes +{ + _autoCompletes = autoCompletes; +} + +- (NSArray*)getAutoCompletes +{ + return _autoCompletes; +} +@end + diff --git a/quickdialog/NSMutableArray+IMSExtensions.h b/quickdialog/NSMutableArray+IMSExtensions.h new file mode 100644 index 00000000..16573d81 --- /dev/null +++ b/quickdialog/NSMutableArray+IMSExtensions.h @@ -0,0 +1,16 @@ +// +// NSMutableArray+IMSExtensions.h +// QuickDialog +// +// Created by Iain Stubbs on 16/02/12. +// Copyright (c) 2012 Parallel ThirtyEight South. All rights reserved. +// + +#import + +@interface NSMutableArray (IMSExtensions) + +- (NSString*)concatStrings; + +@end + diff --git a/quickdialog/NSMutableArray+IMSExtensions.m b/quickdialog/NSMutableArray+IMSExtensions.m new file mode 100644 index 00000000..27151a7a --- /dev/null +++ b/quickdialog/NSMutableArray+IMSExtensions.m @@ -0,0 +1,19 @@ +// +// NSMutableArray+IMSExtensions.m +// PsychAu +// +// Created by Iain Stubbs on 30/01/12. +// Copyright (c) 2012 Parallel ThirtyEight South. All rights reserved. +// + +#import "NSMutableArray+IMSExtensions.h" + +@implementation NSMutableArray (IMSExtensions) + +- (NSString*)concatStrings +{ + NSArray *array = [NSArray arrayWithArray:self]; + return [array componentsJoinedByString: @""]; +} + +@end diff --git a/quickdialog/NSMutableArray+MoveObject.h b/quickdialog/NSMutableArray+MoveObject.h new file mode 100644 index 00000000..17cb1d1e --- /dev/null +++ b/quickdialog/NSMutableArray+MoveObject.h @@ -0,0 +1,7 @@ +#import + +@interface NSMutableArray (MoveObject) + +- (void)moveObjectFromIndex:(NSUInteger)from toIndex:(NSUInteger)to; + +@end \ No newline at end of file diff --git a/quickdialog/NSMutableArray+MoveObject.m b/quickdialog/NSMutableArray+MoveObject.m new file mode 100644 index 00000000..786fcb1f --- /dev/null +++ b/quickdialog/NSMutableArray+MoveObject.m @@ -0,0 +1,19 @@ +#import "NSMutableArray+MoveObject.h" + +@implementation NSMutableArray (MoveObject) + +- (void)moveObjectFromIndex:(NSUInteger)from toIndex:(NSUInteger)to +{ + if (to == from) + return; + + id objectToMove = [self objectAtIndex:from]; + [self removeObjectAtIndex:from]; + if (to >= [self count]) { + [self addObject:objectToMove]; + } else { + [self insertObject:objectToMove atIndex:to]; + } +} +@end + diff --git a/quickdialog/QAutoEntryElement.h b/quickdialog/QAutoEntryElement.h new file mode 100644 index 00000000..e0ea7ebd --- /dev/null +++ b/quickdialog/QAutoEntryElement.h @@ -0,0 +1,41 @@ +// created by Iain Stubbs but based on the QEntryElement.h +// +// Copyright 2011 ESCOZ Inc - http://escoz.com +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software distributed under +// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +// ANY KIND, either express or implied. See the License for the specific language governing +// permissions and limitations under the License. +// +#import "QLabelElement.h" +#import "DOAutocompleteTextField.h" + +@interface QAutoEntryElement : QEntryElement + +@property(nonatomic, retain) NSString *textValue; +@property(nonatomic, retain) NSString *placeholder; +@property(nonatomic, retain) NSArray *autoCompleteValues; +@property(nonatomic, retain) UIColor *autoCompleteColor; +@property(assign) BOOL hiddenToolbar; +@property(nonatomic, retain) NSString *lastAutoComplete; + +@property(nonatomic, unsafe_unretained) id delegate; + +@property(nonatomic) UITextAutocapitalizationType autocapitalizationType; // default is UITextAutocapitalizationTypeSentences +@property(nonatomic) UITextAutocorrectionType autocorrectionType; // default is UITextAutocorrectionTypeDefault +@property(nonatomic) UIKeyboardType keyboardType; // default is UIKeyboardTypeDefault +@property(nonatomic) UIKeyboardAppearance keyboardAppearance; // default is UIKeyboardAppearanceDefault +@property(nonatomic) UIReturnKeyType returnKeyType; // default is UIReturnKeyDefault (See note under UIReturnKeyType enum) +@property(nonatomic) BOOL enablesReturnKeyAutomatically; // default is NO (when YES, will automatically disable return key when text widget has zero-length contents, and will automatically enable when text widget has non-zero-length contents) +@property(nonatomic,getter=isSecureTextEntry) BOOL secureTextEntry; // default is NO + +- (QAutoEntryElement *)init; + +- (QAutoEntryElement *)initWithTitle:(NSString *)string value:(NSString *)param placeholder:(NSString *)string1; + +@end diff --git a/quickdialog/QAutoEntryElement.m b/quickdialog/QAutoEntryElement.m new file mode 100644 index 00000000..5a519299 --- /dev/null +++ b/quickdialog/QAutoEntryElement.m @@ -0,0 +1,107 @@ +// created by Iain Stubbs but based on QEntryTableViewCell.m +// +// Copyright 2011 ESCOZ Inc - http://escoz.com +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software distributed under +// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +// ANY KIND, either express or implied. See the License for the specific language governing +// permissions and limitations under the License. +// + +@implementation QAutoEntryElement + +@synthesize textValue; +@synthesize placeholder; +@synthesize hiddenToolbar; +@synthesize autoCompleteValues = _autoCompleteValues; +@synthesize lastAutoComplete; +@synthesize autoCompleteColor; + +@synthesize delegate = _delegate; + +- (QAutoEntryElement *)init { + self = [super init]; + if (self){ + self.autocapitalizationType = UITextAutocapitalizationTypeSentences; + self.autocorrectionType = UITextAutocorrectionTypeDefault; + self.keyboardType = UIKeyboardTypeDefault; + self.keyboardAppearance = UIKeyboardAppearanceDefault; + self.returnKeyType = UIReturnKeyDefault; + self.enablesReturnKeyAutomatically = NO; + self.secureTextEntry = NO; + } + return self; +} + +- (QAutoEntryElement *)initWithTitle:(NSString *)string value:(NSString *)param placeholder:(NSString *)string1; +{ + self = [self init]; + if (self) { + _title = string; + textValue = param; + placeholder = string1; + } + return self; +} + + +- (UITableViewCell *)getCellForTableView:(QuickDialogTableView *)tableView controller:(QuickDialogController *)controller { + + QAutoEntryTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"QuickformEntryElement"]; + if (cell==nil){ + cell = [[QAutoEntryTableViewCell alloc] init]; + } + + [cell prepareForElement:self inTableView:tableView]; + return cell; +} + +- (void)selected:(QuickDialogTableView *)tableView controller:(QuickDialogController *)controller indexPath:(NSIndexPath *)indexPath { + [super selected:tableView controller:controller indexPath:indexPath]; + +} + +- (void)fetchValueIntoObject:(id)obj { + if (_key==nil) + return; + + [obj setValue:textValue forKey:_key]; +} + +- (NSString *)textField:(DOAutocompleteTextField *)textField completionForPrefix:(NSString *)prefix +{ + NSString* lowPrefix = [prefix lowercaseString]; + for (NSString *string in [textField getAutoCompletes]) + { + NSString* strlower = [string lowercaseString]; + if([strlower hasPrefix:lowPrefix]) + { + NSRange range = NSMakeRange(0,prefix.length); + lastAutoComplete = string; + return [string stringByReplacingCharactersInRange:range withString:@""]; + } + } + lastAutoComplete = @""; + return @""; +} + + + + +#pragma mark - UITextInputTraits + +@synthesize autocorrectionType = _autocorrectionType; +@synthesize autocapitalizationType = _autocapitalizationType; +@synthesize keyboardType = _keyboardType; +@synthesize keyboardAppearance = _keyboardAppearance; +@synthesize returnKeyType = _returnKeyType; +@synthesize enablesReturnKeyAutomatically = _enablesReturnKeyAutomatically; +@synthesize secureTextEntry = _secureTextEntry; + +@end + diff --git a/quickdialog/QAutoEntryTableViewCell.h b/quickdialog/QAutoEntryTableViewCell.h new file mode 100644 index 00000000..41cc5b47 --- /dev/null +++ b/quickdialog/QAutoEntryTableViewCell.h @@ -0,0 +1,45 @@ +// created by Iain Stubbs but based on QEntryTableViewCell.h +// +// Copyright 2011 ESCOZ Inc - http://escoz.com +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software distributed under +// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +// ANY KIND, either express or implied. See the License for the specific language governing +// permissions and limitations under the License. +// + +#import +#import +#import "QuickDialog.h" +#import "DOAutocompleteTextField.h" + +@class QEntryElement; +@class QuickDialogTableView; + + +@interface QAutoEntryTableViewCell : QEntryTableViewCell { + + DOAutocompleteTextField *txtField; + NSArray*autoCompleteValues; + UIColor *autoColor; + +@protected +} + +@property(nonatomic, strong) DOAutocompleteTextField *autoCompleteField; +@property(nonatomic, retain) NSArray *autoCompleteValues; +@property(nonatomic, strong) NSString *lastAutoComplete; + + +- (void)prepareForElement:(QEntryElement *)element inTableView:(QuickDialogTableView *)tableView; + +- (void)createSubviews; + +- (void)recalculateEntryFieldPosition; + +@end \ No newline at end of file diff --git a/quickdialog/QAutoEntryTableViewCell.m b/quickdialog/QAutoEntryTableViewCell.m new file mode 100644 index 00000000..2512f634 --- /dev/null +++ b/quickdialog/QAutoEntryTableViewCell.m @@ -0,0 +1,142 @@ +// created by Iain Stubbs but based on QEntryTableViewCell.m +// +// Copyright 2011 ESCOZ Inc - http://escoz.com +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software distributed under +// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +// ANY KIND, either express or implied. See the License for the specific language governing +// permissions and limitations under the License. +// + +@implementation QAutoEntryTableViewCell { + NSString *_lastAutoComplete; + QAutoEntryElement *_autoEntryElement; +} + +@synthesize autoCompleteField = _autoCompleteField; +@synthesize autoCompleteValues; +@synthesize lastAutoComplete = _lastAutoComplete; + + +- (void)createSubviews { + _autoCompleteField = [[DOAutocompleteTextField alloc] init]; + _autoCompleteField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; + _autoCompleteField.borderStyle = UITextBorderStyleNone; + _autoCompleteField.delegate = self; + _autoCompleteField.clearButtonMode = UITextFieldViewModeWhileEditing; + _autoCompleteField.autoresizingMask = ( UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight); + [_autoCompleteField addTarget:self action:@selector(textFieldEditingChanged:) forControlEvents:UIControlEventEditingChanged]; + [self.contentView addSubview:_autoCompleteField]; + [self setNeedsLayout]; +} + +- (QAutoEntryTableViewCell *)init { + self = [self initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"QuickformEntryElement"]; + if (self!=nil){ + self.selectionStyle = UITableViewCellSelectionStyleNone; + + [self createSubviews]; + } + return self; +} + + +- (void)prepareForElement:(QEntryElement *)element inTableView:(QuickDialogTableView *)tableView{ + _quickformTableView = tableView; + _autoCompleteField.delegate = self; + + _entryElement = element; + _autoEntryElement = (QAutoEntryElement *)element; + + self.textLabel.text = _entryElement.title; + self.autoCompleteValues = _autoEntryElement.autoCompleteValues; + _autoCompleteField.text = _autoEntryElement.textValue; + _autoCompleteField.placeholder = _autoEntryElement.placeholder; + _autoCompleteField.autocapitalizationType = _autoEntryElement.autocapitalizationType; + _autoCompleteField.autocorrectionType = _autoEntryElement.autocorrectionType; + _autoCompleteField.keyboardType = _autoEntryElement.keyboardType; + _autoCompleteField.keyboardAppearance = _autoEntryElement.keyboardAppearance; + _autoCompleteField.secureTextEntry = _autoEntryElement.secureTextEntry; + _autoCompleteField.autocompleteTextColor = _autoEntryElement.autoCompleteColor; + _autoCompleteField.returnKeyType = _autoEntryElement.returnKeyType; + _autoCompleteField.enablesReturnKeyAutomatically = _autoEntryElement.enablesReturnKeyAutomatically; + + if (_autoEntryElement.hiddenToolbar){ + _autoCompleteField.inputAccessoryView = nil; + } else { + _autoCompleteField.inputAccessoryView = [self createActionBar]; + } + + [self updatePrevNextStatus]; +} + +- (BOOL)handleActionBarDone:(UIBarButtonItem *)doneButton { + [_autoCompleteField resignFirstResponder]; + return [super handleActionBarDone:doneButton]; +} + + +-(void)recalculateEntryFieldPosition { + _entryElement.parentSection.entryPosition = CGRectZero; + _autoCompleteField.frame = [self calculateFrameForEntryElement]; + CGRect labelFrame = self.textLabel.frame; + self.textLabel.frame = CGRectMake(labelFrame.origin.x, labelFrame.origin.y, + _entryElement.parentSection.entryPosition.origin.x-20, labelFrame.size.height); +} + +- (void)layoutSubviews { + [super layoutSubviews]; + [self recalculateEntryFieldPosition]; +} + +- (void)prepareForReuse { + _quickformTableView = nil; + _entryElement = nil; +} + + +-(void)textFieldDidEndEditing:(UITextField *)textField { + _autoCompleteField.text = self.lastAutoComplete; + _entryElement.textValue = _autoCompleteField.text; +} + +- (void)textFieldEditingChanged:(UITextField *)textField { + _entryElement.textValue = _autoCompleteField.text; +} + +- (BOOL)textFieldShouldReturn:(UITextField *)textField { + BOOL result = [super textFieldShouldReturn:textField]; + [textField resignFirstResponder]; + return result; +} +- (BOOL)becomeFirstResponder { + [_autoCompleteField becomeFirstResponder]; + return YES; +} + + +#pragma mark - DOAutocompleteTextFieldDelegate +- (NSString *)textField:(DOAutocompleteTextField *)textField completionForPrefix:(NSString *)prefix +{ + NSString* lowPrefix = [prefix lowercaseString]; + + for (NSString *string in autoCompleteValues) + { + NSString* strlower = [string lowercaseString]; + if([strlower hasPrefix:lowPrefix]) + { + NSRange range = NSMakeRange(0,prefix.length); + _lastAutoComplete = string; + return [string stringByReplacingCharactersInRange:range withString:@""]; + } + } + _lastAutoComplete = @""; + return @""; +} + +@end \ No newline at end of file diff --git a/quickdialog/QBadgeElement.m b/quickdialog/QBadgeElement.m index 9673f84e..e4456763 100644 --- a/quickdialog/QBadgeElement.m +++ b/quickdialog/QBadgeElement.m @@ -43,6 +43,7 @@ - (UITableViewCell *)getCellForTableView:(QuickDialogTableView *)tableView contr cell.badgeLabel.text = _badge; cell.accessoryType = UITableViewCellAccessoryNone; cell.selectionStyle = UITableViewCellSelectionStyleNone; + cell.imageView.image = _image; cell.accessoryType = self.sections!= nil || self.controllerAction!=nil ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone; cell.selectionStyle = self.sections!= nil || self.controllerAction!=nil ? UITableViewCellSelectionStyleBlue: UITableViewCellSelectionStyleNone; return cell; diff --git a/quickdialog/QBindingEvaluator.h b/quickdialog/QBindingEvaluator.h index 78e14605..d5af4c4b 100644 --- a/quickdialog/QBindingEvaluator.h +++ b/quickdialog/QBindingEvaluator.h @@ -25,4 +25,8 @@ - (void)bindSection:(QSection *)section toProperties:(id)object; +- (void)bindRootElement:(QRootElement *)element toCollection:(NSArray *)items; + +- (void)fetchValueFromObject:(QElement *)element toData:(id)data; + @end \ No newline at end of file diff --git a/quickdialog/QBindingEvaluator.m b/quickdialog/QBindingEvaluator.m index c7cf40be..d552fe28 100644 --- a/quickdialog/QBindingEvaluator.m +++ b/quickdialog/QBindingEvaluator.m @@ -22,6 +22,7 @@ + (BOOL)stringIsEmpty:(NSString *)aString; @implementation QBindingEvaluator { QRootBuilder *_builder; } + - (id)init { self = [super init]; if (self) { @@ -31,6 +32,7 @@ - (id)init { return self; } + - (void)bindObject:(id)object toData:(id)data { if (![object respondsToSelector:@selector(bind)]) return; @@ -46,16 +48,19 @@ - (void)bindObject:(id)object toData:(id)data { NSString *valueName = [((NSString *) [bindingParams objectAtIndex:1]) stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; if ([propName isEqualToString:@"iterate"] && [object isKindOfClass:[QSection class]]) { - [self bindSection:(QSection *)object toCollection:[data valueForKey:valueName]]; - + [self bindSection:(QSection *)object toCollection:[data valueForKeyPath:valueName]]; + + } else if ([propName isEqualToString:@"iterate"] && [object isKindOfClass:[QRootElement class]]) { + [self bindRootElement:(QRootElement *)object toCollection:[data valueForKeyPath:valueName]]; + } else if ([propName isEqualToString:@"iterateproperties"] && [object isKindOfClass:[QSection class]]) { - [self bindSection:(QSection *)object toProperties:[data valueForKey:valueName]]; + [self bindSection:(QSection *)object toProperties:[data valueForKeyPath:valueName]]; } else if ([valueName isEqualToString:@"self"]) { - [QRootBuilder trySetProperty:propName onObject:object withValue:data]; + [QRootBuilder trySetProperty:propName onObject:object withValue:data localized:NO]; } else { - [QRootBuilder trySetProperty:propName onObject:object withValue:[data valueForKey:valueName]]; + [QRootBuilder trySetProperty:propName onObject:object withValue:[data valueForKeyPath:valueName] localized:NO]; } } } @@ -82,14 +87,42 @@ - (void)bindSection:(QSection *)section toCollection:(NSArray *)items { } } +- (void)bindRootElement:(QRootElement *)element toCollection:(NSArray *)items { + [element.sections removeAllObjects]; + for (id item in items){ + QSection *section = [_builder buildSectionWithObject:element.sectionTemplate]; + [element addSection:section]; + [section bindToObject:item]; + } + if (element.sections.count==0 && element.emptyMessage !=nil){ + QSection *section = [[QSection alloc] init]; + [section addElement:[[QTextElement alloc] initWithText:element.emptyMessage]]; + [element addSection:section]; + } +} + - (void)bindSection:(QSection *)section toProperties:(NSDictionary *)object { [section.elements removeAllObjects]; for (id item in [object allKeys]){ QElement *element = [_builder buildElementWithObject:section.elementTemplate]; [section addElement:element]; - [element bindToObject:[NSDictionary dictionaryWithObjectsAndKeys:item, @"key", [object valueForKey:item], @"value", nil]]; } } +- (void)fetchValueFromObject:(QElement *)element toData:(id)data { + if (element.bind == nil || ([element.bind length] == 0)) { + return; + } + + for (NSString *each in [element.bind componentsSeparatedByString:@","]) + { + NSArray *bindingParams = [each componentsSeparatedByString:@":"]; + NSString *propName = [((NSString *) [bindingParams objectAtIndex:0]) stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + NSString *valueName = [((NSString *) [bindingParams objectAtIndex:1]) stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + + [data setValue:[element valueForKey:propName] forKey:valueName]; + } + +} @end \ No newline at end of file diff --git a/quickdialog/QBooleanElement.h b/quickdialog/QBooleanElement.h index 6c484aa1..00b1ac28 100644 --- a/quickdialog/QBooleanElement.h +++ b/quickdialog/QBooleanElement.h @@ -17,7 +17,6 @@ @interface QBooleanElement : QLabelElement { BOOL _boolValue; BOOL _enabled; -@private UIImage *_onImage; UIImage *_offImage; } diff --git a/quickdialog/QBooleanElement.m b/quickdialog/QBooleanElement.m index 884d6525..57b4bb09 100644 --- a/quickdialog/QBooleanElement.m +++ b/quickdialog/QBooleanElement.m @@ -12,6 +12,8 @@ // permissions and limitations under the License. // +#import + @implementation QBooleanElement { __unsafe_unretained QuickDialogController *_controller; } @@ -28,8 +30,8 @@ - (QBooleanElement *)init { - (QBooleanElement *)initWithTitle:(NSString *)title BoolValue:(BOOL)value { self = [self initWithTitle:title Value:nil]; - _boolValue = value; - _enabled = YES; + self.boolValue = value; + self.enabled = YES; return self; } @@ -48,18 +50,19 @@ - (UITableViewCell *)getCellForTableView:(QuickDialogTableView *)tableView contr _controller = controller; if ((_onImage==nil) && (_offImage==nil)) { UISwitch *boolSwitch = [[UISwitch alloc] init]; - boolSwitch.on = _boolValue; - boolSwitch.enabled = _enabled; + boolSwitch.on = self.boolValue; + boolSwitch.enabled = self.enabled; [boolSwitch addTarget:self action:@selector(switched:) forControlEvents:UIControlEventValueChanged]; cell.accessoryView = boolSwitch; } else { UIButton *boolButton = [[UIButton alloc] init]; - [boolButton setImage:self.offImage forState:UIControlStateNormal]; - [boolButton setImage:self.onImage forState:UIControlStateSelected]; + [boolButton setImage:self.offImage forState: UIControlStateNormal]; + [boolButton setImage:self.onImage forState: UIControlStateSelected]; + [boolButton setImage:self.onImage forState: UIControlStateSelected | UIControlStateDisabled]; cell.accessoryView = boolButton; - boolButton.enabled = _enabled; - boolButton.selected = _boolValue; + boolButton.enabled = self.enabled; + boolButton.selected = self.boolValue; [boolButton sizeToFit]; [boolButton addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside]; } @@ -68,32 +71,43 @@ - (UITableViewCell *)getCellForTableView:(QuickDialogTableView *)tableView contr - (void)selected:(QuickDialogTableView *)tableView controller:(QuickDialogController *)controller indexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; - _boolValue = !_boolValue; - if ([cell.accessoryView class] == [UIImageView class]){ - ((UIImageView *)cell.accessoryView).image = _boolValue ? _onImage : _offImage; + self.boolValue = !self.boolValue; + if ([cell.accessoryView class] == [UIButton class]) { + ((UIButton *)cell.accessoryView).selected = self.boolValue; + } + else if ([cell.accessoryView class] == [UISwitch class]) { + [((UISwitch *)cell.accessoryView) setOn:self.boolValue animated:YES]; } - [tableView deselectRowAtIndexPath:indexPath animated:YES]; - if (_sections!=nil) - [self handleElementSelected:controller]; + + if (self.controllerAction==nil) + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + [self handleElementSelected:controller]; } - (void)buttonPressed:(UIButton *)boolButton { - _boolValue = !boolButton.selected; + self.boolValue = !boolButton.selected; boolButton.selected = _boolValue; - if (_controller!=nil && self.controllerAction!=nil) - [self handleElementSelected:_controller]; + if (_controller!=nil && self.controllerAccessoryAction!=nil) { + SEL selector = NSSelectorFromString(self.controllerAccessoryAction); + if ([_controller respondsToSelector:selector]) { + objc_msgSend(_controller,selector, self); + } else { + NSLog(@"No method '%@' was found on controller %@", self.controllerAccessoryAction, [_controller class]); + } + } } - (void)switched:(id)boolSwitch { - _boolValue = ((UISwitch *)boolSwitch).on; - if (_controller!=nil && self.controllerAction!=nil) + self.boolValue = ((UISwitch *)boolSwitch).on; + if ((_controller != nil && self.controllerAction != nil) || _onSelected != nil) { [self handleElementSelected:_controller]; + } } - (void)fetchValueIntoObject:(id)obj { if (_key==nil) return; - [obj setValue:[NSNumber numberWithBool:_boolValue] forKey:_key]; + [obj setValue:[NSNumber numberWithBool:self.boolValue] forKey:_key]; } diff --git a/quickdialog/QButtonElement.h b/quickdialog/QButtonElement.h index c371dd3e..f33d8456 100644 --- a/quickdialog/QButtonElement.h +++ b/quickdialog/QButtonElement.h @@ -14,9 +14,9 @@ #import "QLabelElement.h" -@interface QButtonElement : QLabelElement { +@interface QButtonElement : QLabelElement -} +@property (nonatomic, assign, getter=isEnabled) BOOL enabled; - (QButtonElement *)init; diff --git a/quickdialog/QButtonElement.m b/quickdialog/QButtonElement.m index daffcc18..2fa81f7a 100644 --- a/quickdialog/QButtonElement.m +++ b/quickdialog/QButtonElement.m @@ -13,14 +13,19 @@ // @implementation QButtonElement +@synthesize enabled = _enabled; - (QButtonElement *)init { self = [super init]; + if (self) { + self.enabled = YES; + } return self; } - (QButtonElement *)initWithTitle:(NSString *)title { self = [super initWithTitle:title Value:nil]; + self.enabled = YES; return self; } @@ -29,15 +34,23 @@ - (UITableViewCell *)getCellForTableView:(QuickDialogTableView *)tableView contr if (cell == nil){ cell= [[QTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"QuickformButtonElement"]; } - cell.selectionStyle = UITableViewCellSelectionStyleBlue; + if (self.enabled) { + cell.selectionStyle = UITableViewCellSelectionStyleBlue; + cell.textLabel.textColor = [UIColor colorWithRed:50.0f/255.0f green:79.0f/255.0f blue:133.0f/255.0f alpha:1]; + } else { + cell.selectionStyle = UITableViewCellSelectionStyleNone; + cell.textLabel.textColor = [UIColor lightGrayColor]; + } + cell.textLabel.text = _title; cell.textLabel.textAlignment = UITextAlignmentCenter; - cell.textLabel.textColor = [UIColor colorWithRed:50.0f/255.0f green:79.0f/255.0f blue:133.0f/255.0f alpha:1]; return cell; } - (void)selected:(QuickDialogTableView *)tableView controller:(QuickDialogController *)controller indexPath:(NSIndexPath *)indexPath { - [super selected:tableView controller:controller indexPath:indexPath]; + if (self.enabled) { + [super selected:tableView controller:controller indexPath:indexPath]; + } [tableView deselectRowAtIndexPath:indexPath animated:YES]; } diff --git a/quickdialog/QDateEntryTableViewCell.h b/quickdialog/QDateEntryTableViewCell.h index 619ada74..59411848 100644 --- a/quickdialog/QDateEntryTableViewCell.h +++ b/quickdialog/QDateEntryTableViewCell.h @@ -26,4 +26,6 @@ @property(nonatomic, retain) UILabel *centeredLabel; + ++ (UIDatePicker *)getPickerForDate; @end \ No newline at end of file diff --git a/quickdialog/QDateEntryTableViewCell.m b/quickdialog/QDateEntryTableViewCell.m index 0ecadcd6..4e8522d4 100644 --- a/quickdialog/QDateEntryTableViewCell.m +++ b/quickdialog/QDateEntryTableViewCell.m @@ -16,6 +16,8 @@ #import "QDateEntryTableViewCell.h" #import "QDateTimeInlineElement.h" +UIDatePicker *QDATEENTRY_GLOBAL_PICKER; + @implementation QDateEntryTableViewCell @synthesize pickerView = _pickerView; @@ -26,22 +28,44 @@ - (QDateEntryTableViewCell *)init { self = [self initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"QuickformDateTimeInlineElement"]; if (self!=nil){ [self createSubviews]; - self.selectionStyle = UITableViewCellSelectionStyleGray; + self.selectionStyle = UITableViewCellSelectionStyleBlue; } return self; } -- (void)createSubviews { - [super createSubviews]; - _textField.hidden = YES; ++ (UIDatePicker *)getPickerForDate { + QDATEENTRY_GLOBAL_PICKER = [[UIDatePicker alloc] init]; + return QDATEENTRY_GLOBAL_PICKER; +} - _pickerView = [[UIDatePicker alloc] init]; - [_pickerView sizeToFit]; - _pickerView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight); - [_pickerView addTarget:self action:@selector(dateChanged:) - forControlEvents:UIControlEventValueChanged]; +- (void)textFieldDidEndEditing:(UITextField *)textField { + [super textFieldDidEndEditing:textField]; + self.selected = NO; + [_pickerView removeTarget:self action:@selector(dateChanged:) forControlEvents:UIControlEventValueChanged]; + _pickerView = nil; + +} +- (void)textFieldDidBeginEditing:(UITextField *)textField { + QDateTimeInlineElement *const element = ((QDateTimeInlineElement *) _entryElement); + + _pickerView = [QDateEntryTableViewCell getPickerForDate]; + [_pickerView sizeToFit]; _textField.inputView = _pickerView; + [_pickerView addTarget:self action:@selector(dateChanged:) forControlEvents:UIControlEventValueChanged]; + _pickerView.datePickerMode = element.mode; + _pickerView.maximumDate = element.maximumDate; + _pickerView.minimumDate = element.minimumDate; + if (element.dateValue!=nil) + _pickerView.date = element.dateValue; + + [super textFieldDidBeginEditing:textField]; + self.selected = YES; +} + +- (void)createSubviews { + [super createSubviews]; + _textField.hidden = YES; self.centeredLabel = [[UILabel alloc] init]; self.centeredLabel.textColor = [UIColor colorWithRed:0.243 green:0.306 blue:0.435 alpha:1.0]; @@ -54,12 +78,15 @@ - (void)createSubviews { } - (void) dateChanged:(id)sender{ - ((QDateTimeInlineElement *) _entryElement).dateValue = _pickerView.date; + QDateTimeInlineElement *const element = ((QDateTimeInlineElement *) _entryElement); + element.dateValue = _pickerView.date; [self prepareForElement:_entryElement inTableView:_quickformTableView]; + if (element.onValueChanged!=nil) + element.onValueChanged(); + } - (void)prepareForElement:(QEntryElement *)element inTableView:(QuickDialogTableView *)tableView { - QDateTimeInlineElement *entry = (QDateTimeInlineElement *)element; [super prepareForElement:element inTableView:tableView]; QDateTimeInlineElement *dateElement = ((QDateTimeInlineElement *) element); @@ -83,27 +110,21 @@ - (void)prepareForElement:(QEntryElement *)element inTableView:(QuickDialogTable [dateFormatter setTimeStyle:NSDateFormatterShortStyle]; break; } - - if (!entry.centerLabel){ + + if (!dateElement.centerLabel){ self.textLabel.text = element.title; - self.selectionStyle = UITableViewCellSelectionStyleNone; self.centeredLabel.text = nil; self.detailTextLabel.text = [dateFormatter stringFromDate:dateElement.dateValue]; } else { - self.selectionStyle = UITableViewCellSelectionStyleBlue; self.textLabel.text = nil; self.centeredLabel.text = [dateFormatter stringFromDate:dateElement.dateValue]; } - + _textField.text = [dateFormatter stringFromDate:dateElement.dateValue]; - _pickerView.datePickerMode = dateElement.mode; - if (dateElement.dateValue!=nil) - _pickerView.date = dateElement.dateValue; _textField.placeholder = dateElement.placeholder; - _textField.inputAccessoryView.hidden = entry.hiddenToolbar; + _textField.inputAccessoryView.hidden = dateElement.hiddenToolbar; } - @end \ No newline at end of file diff --git a/quickdialog/QDateTimeElement.h b/quickdialog/QDateTimeElement.h index d03365c1..dd2f7cb5 100644 --- a/quickdialog/QDateTimeElement.h +++ b/quickdialog/QDateTimeElement.h @@ -25,6 +25,7 @@ } @property(nonatomic, retain) NSDate *dateValue; +@property(nonatomic, assign) NSNumber *ticksValue; @property (assign) UIDatePickerMode mode; diff --git a/quickdialog/QDateTimeElement.m b/quickdialog/QDateTimeElement.m index 1ec68053..e933ec88 100644 --- a/quickdialog/QDateTimeElement.m +++ b/quickdialog/QDateTimeElement.m @@ -41,6 +41,14 @@ - (void)setDateValue:(NSDate *)date { [self initializeRoot]; } +- (void)setTicksValue:(NSNumber *)ticks { + [self setDateValue:[NSDate dateWithTimeIntervalSince1970:ticks.doubleValue]]; +} + +-(NSNumber *)ticksValue { + return [NSNumber numberWithDouble:[self.dateValue timeIntervalSince1970]]; +} + - (UIDatePickerMode)mode { return _mode; } @@ -98,7 +106,6 @@ - (void)initializeRoot { dateForSection = NSDate.date; } QSection *section = [[QSection alloc] initWithTitle:(_mode == UIDatePickerModeDateAndTime ? @"\n" : @"\n\n")]; - if (_mode == UIDatePickerModeDate || _mode == UIDatePickerModeDateAndTime){ QDateTimeInlineElement *dateElement = (QDateTimeInlineElement *) [[QDateTimeInlineElement alloc] initWithKey:@"date"]; dateElement.dateValue = dateForSection; diff --git a/quickdialog/QDateTimeInlineElement.h b/quickdialog/QDateTimeInlineElement.h index 622fe660..66f3c969 100644 --- a/quickdialog/QDateTimeInlineElement.h +++ b/quickdialog/QDateTimeInlineElement.h @@ -23,14 +23,22 @@ } @property(nonatomic, retain) NSDate *dateValue; +@property(nonatomic, assign) NSNumber *ticksValue; @property (assign) UIDatePickerMode mode; @property(nonatomic) BOOL centerLabel; +@property(nonatomic, strong) NSDate *maximumDate; + +@property(nonatomic, strong) NSDate *minimumDate; + + - (QDateTimeInlineElement *)initWithDate:(NSDate *)date; - (QDateTimeInlineElement *)initWithTitle:(NSString *)string date:(NSDate *)date; +@property(nonatomic, copy) void (^onValueChanged)(void); + @end \ No newline at end of file diff --git a/quickdialog/QDateTimeInlineElement.m b/quickdialog/QDateTimeInlineElement.m index d694fcc4..d0bc0070 100644 --- a/quickdialog/QDateTimeInlineElement.m +++ b/quickdialog/QDateTimeInlineElement.m @@ -12,22 +12,34 @@ // permissions and limitations under the License. // -#import "QDateTimeInlineElement.h" #import "QDateEntryTableViewCell.h" -@implementation QDateTimeInlineElement +@implementation QDateTimeInlineElement { +@private + NSDate *_maximumDate; + NSDate *_minimumDate; + + void (^_onValueChanged)(); + +} @synthesize dateValue = _dateValue; @synthesize mode = _mode; @synthesize centerLabel = _centerLabel; +@synthesize maximumDate = _maximumDate; +@synthesize minimumDate = _minimumDate; +@synthesize onValueChanged = _onValueChanged; + - (QDateTimeInlineElement *)init { self = [super init]; + _dateValue = [NSDate date]; return self; } - (QDateTimeInlineElement *)initWithKey:(NSString *)key { self = [super initWithKey:key]; + _dateValue = [NSDate date]; return self; } @@ -40,9 +52,17 @@ - (QDateTimeInlineElement *)initWithTitle:(NSString *)string date:(NSDate *)date return self; } + +- (void)setTicksValue:(NSNumber *)ticks { + self.dateValue = [NSDate dateWithTimeIntervalSince1970:ticks.doubleValue]; +} + +-(NSNumber *)ticksValue { + return [NSNumber numberWithDouble:[self.dateValue timeIntervalSince1970]]; +} + - (QDateTimeInlineElement *)initWithDate:(NSDate *)date { return [self initWithTitle:nil date:date]; - } - (UITableViewCell *)getCellForTableView:(QuickDialogTableView *)tableView controller:(QuickDialogController *)controller { @@ -52,6 +72,8 @@ - (UITableViewCell *)getCellForTableView:(QuickDialogTableView *)tableView contr cell = [[QDateEntryTableViewCell alloc] init]; } [cell prepareForElement:self inTableView:tableView]; + cell.imageView.image = self.image; + cell.selectionStyle = UITableViewCellSelectionStyleBlue ; return cell; } @@ -62,5 +84,4 @@ - (void)fetchValueIntoObject:(id)obj { [obj setValue:_dateValue forKey:_key]; } - @end \ No newline at end of file diff --git a/quickdialog/QDecimalTableViewCell.m b/quickdialog/QDecimalTableViewCell.m index d4bad537..d063958e 100644 --- a/quickdialog/QDecimalTableViewCell.m +++ b/quickdialog/QDecimalTableViewCell.m @@ -13,8 +13,6 @@ // #import "QDecimalTableViewCell.h" -#import "QEntryElement.h" -#import "QDecimalElement.h" @implementation QDecimalTableViewCell { NSNumberFormatter *_numberFormatter; @@ -26,13 +24,13 @@ - (QDecimalTableViewCell *)init { [self createSubviews]; self.selectionStyle = UITableViewCellSelectionStyleNone; _numberFormatter = [[NSNumberFormatter alloc] init]; - [_numberFormatter setUsesSignificantDigits:YES]; + [_numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle]; }; return self; } - (void)createSubviews { - _textField = [[UITextField alloc] init]; + _textField = [[QTextField alloc] init]; [_textField addTarget:self action:@selector(textFieldEditingChanged:) forControlEvents:UIControlEventEditingChanged]; _textField.borderStyle = UITextBorderStyleNone; _textField.keyboardType = UIKeyboardTypeDecimalPad; diff --git a/quickdialog/QDynamicDataSection.m b/quickdialog/QDynamicDataSection.m index 68b4473c..1d77fb60 100644 --- a/quickdialog/QDynamicDataSection.m +++ b/quickdialog/QDynamicDataSection.m @@ -10,11 +10,15 @@ - (QDynamicDataSection *)init { self = [super init]; if (self) { _emptyMessage = @"Empty"; + [self addElement:[[QLoadingElement alloc] init]]; } return self; } - (void)bindToObject:(id)data { + + [self.elements removeAllObjects]; + [super bindToObject:data]; if (self.elements.count>0) //elements exist @@ -28,10 +32,10 @@ - (void)bindToObject:(id)data { NSString *valueName = [((NSString *) [bindingParams objectAtIndex:1]) stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; if ([propName isEqualToString:@"iterate"]) { - collection = [data valueForKey:valueName]; } } + if (collection==nil) [self addElement:[[QLoadingElement alloc] init]]; diff --git a/quickdialog/QElement.h b/quickdialog/QElement.h index 7345166a..33722e8f 100644 --- a/quickdialog/QElement.h +++ b/quickdialog/QElement.h @@ -13,6 +13,7 @@ // #import "QSection.h" #import "QValidator.h" +#import "QTableViewCell.h" @class QuickDialogTableView; @class QuickDialogController; @@ -30,9 +31,9 @@ NSString * _controllerAction; } - @property(nonatomic, copy) void (^onSelected)(void); @property(nonatomic, retain) NSString *controllerAction; +@property(nonatomic, retain) NSString *controllerAccessoryAction; @property(nonatomic) CGFloat height; @@ -43,6 +44,7 @@ @property(nonatomic, retain) NSString *bind; @property(nonatomic, retain) QValidator *validator; +@property (nonatomic) QLabelingPolicy labelingPolicy; - (QElement *)initWithKey:(NSString *)key; @@ -50,6 +52,8 @@ - (void)handleElementSelected:(QuickDialogController *)controller; +- (void)selectedAccessory:(QuickDialogTableView *)tableView controller:(QuickDialogController *)controller indexPath:(NSIndexPath *)indexPath; + - (void)selected:(QuickDialogTableView *)tableView controller:(QuickDialogController *)controller indexPath:(NSIndexPath *)indexPath; @@ -60,6 +64,7 @@ - (void)bindToObject:(id)obj; -(void)validate:(NSMutableArray *)errors; +- (void)fetchValueUsingBindingsIntoObject:(id)object; @end \ No newline at end of file diff --git a/quickdialog/QElement.m b/quickdialog/QElement.m index 8bc9acef..dace7523 100644 --- a/quickdialog/QElement.m +++ b/quickdialog/QElement.m @@ -18,6 +18,7 @@ @implementation QElement { @private NSObject *_object; + NSString *_controllerAccessoryAction; } @synthesize parentSection = _parentSection; @@ -29,9 +30,13 @@ @implementation QElement { @synthesize object = _object; @synthesize height = _height; @synthesize validator = _validator; +@synthesize controllerAccessoryAction = _controllerAccessoryAction; + +@synthesize labelingPolicy = _labelingPolicy; - (QElement *)init { self = [super init]; + return self; } @@ -44,11 +49,17 @@ - (QElement *)initWithKey:(NSString *)key { - (UITableViewCell *)getCellForTableView:(QuickDialogTableView *)tableView controller:(QuickDialogController *)controller { QTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:[NSString stringWithFormat:@"QuickformElementCell%@", self.key]]; if (cell == nil){ - cell = [[QTableViewCell alloc] initWithReuseIdentifier:@"QuickformElementCell"]; + cell = [[QTableViewCell alloc] initWithReuseIdentifier:[NSString stringWithFormat:@"QuickformElementCell%@", self.key]]; } + + cell.textLabel.text = nil; + cell.detailTextLabel.text = nil; + cell.imageView.image = nil; + cell.selectionStyle = UITableViewCellSelectionStyleNone; cell.showsReorderControl = YES; cell.accessoryView = nil; + cell.labelingPolicy = _labelingPolicy; return cell; } @@ -56,7 +67,7 @@ - (void)handleElementSelected:(QuickDialogController *)controller { if (_onSelected!= nil) _onSelected(); - if (self.controllerAction!=NULL){ + if (self.controllerAction!=NULL && !controller.quickDialogTableView.editing){ SEL selector = NSSelectorFromString(self.controllerAction); if ([controller respondsToSelector:selector]) { objc_msgSend(controller,selector, self); @@ -66,6 +77,17 @@ - (void)handleElementSelected:(QuickDialogController *)controller { } } +- (void)selectedAccessory:(QuickDialogTableView *)tableView controller:(QuickDialogController *)controller indexPath:(NSIndexPath *)indexPath{ + if (self.controllerAccessoryAction!=NULL){ + SEL selector = NSSelectorFromString(self.controllerAccessoryAction); + if ([controller respondsToSelector:selector]) { + objc_msgSend(controller,selector, self); + } else { + NSLog(@"No method '%@' was found on controller %@", self.controllerAction, [controller class]); + } + } +} + - (void)selected:(QuickDialogTableView *)tableView controller:(QuickDialogController *)controller indexPath:(NSIndexPath *)indexPath { [[tableView cellForRowAtIndexPath:indexPath] becomeFirstResponder]; @@ -93,4 +115,11 @@ -(void)validate: (NSMutableArray *)errors } } + +- (void)fetchValueUsingBindingsIntoObject:(id)data { + [[QBindingEvaluator new] fetchValueFromObject:self toData:data]; +} + + + @end \ No newline at end of file diff --git a/quickdialog/QEntryElement.h b/quickdialog/QEntryElement.h index c8b37d73..da8a8909 100644 --- a/quickdialog/QEntryElement.h +++ b/quickdialog/QEntryElement.h @@ -17,16 +17,18 @@ @interface QEntryElement : QLabelElement { -@private +@protected NSString *_placeholder; NSString *_textValue; BOOL _hiddenToolbar; } -@property(nonatomic, strong) NSString *textValue; -@property(nonatomic, strong) NSString *placeholder; -@property(assign) BOOL hiddenToolbar; +@property (nonatomic, strong) NSString *textValue; +@property (nonatomic, strong) NSString *placeholder; +@property (nonatomic, strong) NSString *prefix; +@property (nonatomic, strong) NSString *suffix; +@property (assign) BOOL hiddenToolbar; @property(nonatomic, unsafe_unretained) id delegate; @@ -37,8 +39,12 @@ @property(nonatomic) UIReturnKeyType returnKeyType; // default is UIReturnKeyDefault (See note under UIReturnKeyType enum) @property(nonatomic) BOOL enablesReturnKeyAutomatically; // default is NO (when YES, will automatically disable return key when text widget has zero-length contents, and will automatically enable when text widget has non-zero-length contents) @property(nonatomic,getter=isSecureTextEntry) BOOL secureTextEntry; // default is NO +@property(nonatomic, assign) BOOL clearsOnBeginEditing; // default is NO -- (QEntryElement *)init; +- (QEntryElement *)init; - (QEntryElement *)initWithTitle:(NSString *)string Value:(NSString *)param Placeholder:(NSString *)string1; + +- (BOOL)canTakeFocus; + @end \ No newline at end of file diff --git a/quickdialog/QEntryElement.m b/quickdialog/QEntryElement.m index 312d0120..e9c28369 100644 --- a/quickdialog/QEntryElement.m +++ b/quickdialog/QEntryElement.m @@ -16,6 +16,8 @@ @implementation QEntryElement @synthesize textValue = _textValue; @synthesize placeholder = _placeholder; +@synthesize prefix = _prefix; +@synthesize suffix = _suffix; @synthesize hiddenToolbar = _hiddenToolbar; @synthesize delegate = _delegate; @@ -50,7 +52,10 @@ - (UITableViewCell *)getCellForTableView:(QuickDialogTableView *)tableView contr if (cell==nil){ cell = [[QEntryTableViewCell alloc] init]; } - + cell.selectionStyle = UITableViewCellSelectionStyleNone; + cell.textField.enabled = YES; + cell.textField.userInteractionEnabled = YES; + cell.imageView.image = self.image; [cell prepareForElement:self inTableView:tableView]; return cell; } @@ -67,6 +72,9 @@ - (void)fetchValueIntoObject:(id)obj { [obj setValue:_textValue forKey:_key]; } +- (BOOL)canTakeFocus { + return YES; +} #pragma mark - UITextInputTraits @@ -77,5 +85,8 @@ - (void)fetchValueIntoObject:(id)obj { @synthesize returnKeyType = _returnKeyType; @synthesize enablesReturnKeyAutomatically = _enablesReturnKeyAutomatically; @synthesize secureTextEntry = _secureTextEntry; +@synthesize clearsOnBeginEditing = _clearsOnBeginEditing; +@synthesize accessoryType = _accessoryType; + @end \ No newline at end of file diff --git a/quickdialog/QEntryTableViewCell.h b/quickdialog/QEntryTableViewCell.h index d9ba6db9..8f50092c 100644 --- a/quickdialog/QEntryTableViewCell.h +++ b/quickdialog/QEntryTableViewCell.h @@ -19,24 +19,35 @@ @class QEntryElement; @class QuickDialogTableView; +@class QTextField; @interface QEntryTableViewCell : QTableViewCell { QEntryElement *_entryElement; - UITextField *_textField; + QTextField *_textField; @protected __unsafe_unretained QuickDialogTableView *_quickformTableView; } -@property(nonatomic, strong) UITextField *textField; +@property(nonatomic, strong) QTextField *textField; + +- (void)updatePrevNextStatus; - (void)prepareForElement:(QEntryElement *)element inTableView:(QuickDialogTableView *)tableView; +- (UIToolbar *)createActionBar; + - (void)createSubviews; +- (CGRect)calculateFrameForEntryElement; + + - (QEntryElement *)findNextElementToFocusOn; + +- (BOOL)handleActionBarDone:(UIBarButtonItem *)doneButton; + - (QEntryElement *)findPreviousElementToFocusOn; - (void)recalculateEntryFieldPosition; diff --git a/quickdialog/QEntryTableViewCell.m b/quickdialog/QEntryTableViewCell.m index 522902c6..4f351709 100644 --- a/quickdialog/QEntryTableViewCell.m +++ b/quickdialog/QEntryTableViewCell.m @@ -12,8 +12,6 @@ // permissions and limitations under the License. // -#import - @interface QEntryTableViewCell () - (void)handleActionBarPreviousNext:(UISegmentedControl *)control; - (QEntryElement *)findNextElementToFocusOn; @@ -24,11 +22,11 @@ @implementation QEntryTableViewCell { } @synthesize textField = _textField; --(void)createActionBar { +-(UIToolbar *)createActionBar { UIToolbar *actionBar = [[UIToolbar alloc] init]; actionBar.translucent = YES; [actionBar sizeToFit]; - actionBar.barStyle = UIBarStyleBlackTranslucent; + actionBar.barStyle = UIBarStyleBlack; UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Done", @"") style:UIBarButtonItemStyleDone target:self @@ -37,17 +35,17 @@ -(void)createActionBar { _prevNext = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:NSLocalizedString(@"Previous", @""), NSLocalizedString(@"Next", @""), nil]]; _prevNext.momentary = YES; _prevNext.segmentedControlStyle = UISegmentedControlStyleBar; - _prevNext.tintColor = [UIColor darkGrayColor]; + _prevNext.tintColor = actionBar.tintColor; [_prevNext addTarget:self action:@selector(handleActionBarPreviousNext:) forControlEvents:UIControlEventValueChanged]; UIBarButtonItem *prevNextWrapper = [[UIBarButtonItem alloc] initWithCustomView:_prevNext]; UIBarButtonItem *flexible = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; [actionBar setItems:[NSArray arrayWithObjects:prevNextWrapper, flexible, doneButton, nil]]; - _textField.inputAccessoryView = actionBar; + return actionBar; } - (void)createSubviews { - _textField = [[UITextField alloc] init]; + _textField = [[QTextField alloc] init]; _textField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; _textField.borderStyle = UITextBorderStyleNone; _textField.delegate = self; @@ -69,8 +67,12 @@ - (QEntryTableViewCell *)init { } - (CGRect)calculateFrameForEntryElement { - if (_entryElement.title == NULL) { - return CGRectMake(10,10,self.contentView.frame.size.width-10, 24); + int extra = (self.textField.clearButtonMode == UITextFieldViewModeNever) ? 15 :10; + if (_entryElement.title == NULL && _entryElement.image==NULL) { + return CGRectMake(10,10,self.contentView.frame.size.width-10-extra, self.frame.size.height-20); + } + if (_entryElement.title == NULL && _entryElement.image!=NULL){ + return CGRectMake( _entryElement.image.size.width, 10, self.contentView.frame.size.width-10-_entryElement.image.size.width-extra , self.frame.size.height-20); } CGFloat totalWidth = self.contentView.frame.size.width; CGFloat titleWidth = 0; @@ -78,18 +80,26 @@ - (CGRect)calculateFrameForEntryElement { if (CGRectEqualToRect(CGRectZero, _entryElement.parentSection.entryPosition)) { for (QElement *el in _entryElement.parentSection.elements){ if ([el isKindOfClass:[QEntryElement class]]){ + QEntryElement *q = (QEntryElement*)el; + CGFloat imageWidth = q.image == NULL ? 0 : q.image.size.width + 10; CGFloat fontSize = self.textLabel.font.pointSize == 0? 17 : self.textLabel.font.pointSize; CGSize size = [((QEntryElement *)el).title sizeWithFont:[self.textLabel.font fontWithSize:fontSize] forWidth:CGFLOAT_MAX lineBreakMode:UILineBreakModeWordWrap] ; - if (size.width>titleWidth) - titleWidth = size.width; + CGFloat width = size.width + imageWidth; + if (width>titleWidth) + titleWidth = width; } } - _entryElement.parentSection.entryPosition = CGRectMake(titleWidth+20,10,totalWidth-titleWidth-20,24); + _entryElement.parentSection.entryPosition = CGRectMake(titleWidth+20,10,totalWidth-titleWidth-20-extra, self.frame.size.height-20); } return _entryElement.parentSection.entryPosition; } +- (void)updatePrevNextStatus { + [_prevNext setEnabled:[self findPreviousElementToFocusOn]!=nil forSegmentAtIndex:0]; + [_prevNext setEnabled:[self findNextElementToFocusOn]!=nil forSegmentAtIndex:1]; +} + - (void)prepareForElement:(QEntryElement *)element inTableView:(QuickDialogTableView *)tableView{ self.textLabel.text = element.title; @@ -97,24 +107,28 @@ - (void)prepareForElement:(QEntryElement *)element inTableView:(QuickDialogTable _entryElement = element; _textField.text = _entryElement.textValue; _textField.placeholder = _entryElement.placeholder; + _textField.prefix = _entryElement.prefix; + _textField.suffix = _entryElement.suffix; _textField.autocapitalizationType = _entryElement.autocapitalizationType; _textField.autocorrectionType = _entryElement.autocorrectionType; _textField.keyboardType = _entryElement.keyboardType; _textField.keyboardAppearance = _entryElement.keyboardAppearance; _textField.secureTextEntry = _entryElement.secureTextEntry; + _textField.clearsOnBeginEditing = _entryElement.clearsOnBeginEditing; _textField.returnKeyType = _entryElement.returnKeyType; _textField.enablesReturnKeyAutomatically = _entryElement.enablesReturnKeyAutomatically; - + + self.accessoryType = _entryElement.accessoryType; + if (_entryElement.hiddenToolbar){ _textField.inputAccessoryView = nil; } else { - [self createActionBar]; + _textField.inputAccessoryView = [self createActionBar]; } - [_prevNext setEnabled:[self findPreviousElementToFocusOn]!=nil forSegmentAtIndex:0]; - [_prevNext setEnabled:[self findNextElementToFocusOn]!=nil forSegmentAtIndex:1]; + [self updatePrevNextStatus]; } - (void)layoutSubviews { @@ -135,6 +149,7 @@ -(void)recalculateEntryFieldPosition { - (void)prepareForReuse { _quickformTableView = nil; _entryElement = nil; + _textField.textAlignment = UITextAlignmentLeft; } - (void)textFieldEditingChanged:(UITextField *)textFieldEditingChanged { @@ -179,7 +194,6 @@ - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRang - (BOOL)textFieldShouldReturn:(UITextField *)textField { - [_textField resignFirstResponder]; QEntryElement *element = [self findNextElementToFocusOn]; if (element!=nil){ @@ -187,32 +201,44 @@ - (BOOL)textFieldShouldReturn:(UITextField *)textField { if (cell!=nil){ [cell becomeFirstResponder]; } + } else { + [_textField resignFirstResponder]; } if(_entryElement && _entryElement.delegate && [_entryElement.delegate respondsToSelector:@selector(QEntryShouldReturnForElement:andCell:)]){ - [_entryElement.delegate QEntryShouldReturnForElement:_entryElement andCell:self]; + return [_entryElement.delegate QEntryShouldReturnForElement:_entryElement andCell:self]; } return YES; } -- (void) handleActionBarPreviousNext:(UISegmentedControl *)control { +- (void)handleActionBarPreviousNext:(UISegmentedControl *)control { + QEntryElement *element; + const BOOL isNext = control.selectedSegmentIndex == 1; - if (isNext){ + if (isNext) { element = [self findNextElementToFocusOn]; } else { element = [self findPreviousElementToFocusOn]; } - if (element!=nil){ + + if (element != nil) { + UITableViewCell *cell = [_quickformTableView cellForElement:element]; - if (cell!=nil){ + if (cell != nil) { [cell becomeFirstResponder]; - } else { - dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 50 * USEC_PER_SEC); - dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ + } + else { + + [_quickformTableView scrollToRowAtIndexPath:[_quickformTableView indexForElement:element] + atScrollPosition:UITableViewScrollPositionMiddle + animated:YES]; + + dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC); + dispatch_after(popTime, dispatch_get_main_queue(), ^{ UITableViewCell *c = [_quickformTableView cellForElement:element]; - if (c!=nil){ + if (c != nil) { [c becomeFirstResponder]; } }); @@ -221,12 +247,16 @@ - (void) handleActionBarPreviousNext:(UISegmentedControl *)control { } - (BOOL)handleActionBarDone:(UIBarButtonItem *)doneButton { + [self endEditing:YES]; + [self endEditing:NO]; [_textField resignFirstResponder]; + [[[UIApplication sharedApplication] keyWindow] endEditing:YES]; + if(_entryElement && _entryElement.delegate && [_entryElement.delegate respondsToSelector:@selector(QEntryMustReturnForElement:andCell:)]){ [_entryElement.delegate QEntryMustReturnForElement:_entryElement andCell:self]; } - + return NO; } @@ -240,26 +270,32 @@ - (BOOL)resignFirstResponder { } - (QEntryElement *)findPreviousElementToFocusOn { + QEntryElement *previousElement = nil; - for (QElement * e in _entryElement.parentSection.elements){ - if (e == _entryElement) { - return previousElement; - } - else if ([e isKindOfClass:[QEntryElement class]]){ - previousElement = (QEntryElement *)e; + for (QSection *section in _entryElement.parentSection.rootElement.sections) { + for (QElement *e in section.elements) { + if (e == _entryElement) { + return previousElement; + } + else if ([e isKindOfClass:[QEntryElement class]] && [(QEntryElement *)e canTakeFocus]) { + previousElement = (QEntryElement *)e; + } } } return nil; } - (QEntryElement *)findNextElementToFocusOn { + BOOL foundSelf = NO; - for (QElement * e in _entryElement.parentSection.elements){ - if (e == _entryElement) { - foundSelf = YES; - } - else if (foundSelf && [e isKindOfClass:[QEntryElement class]]){ - return (QEntryElement *) e; + for (QSection *section in _entryElement.parentSection.rootElement.sections) { + for (QElement *e in section.elements) { + if (e == _entryElement) { + foundSelf = YES; + } + else if (foundSelf && [e isKindOfClass:[QEntryElement class]] && [(QEntryElement *)e canTakeFocus]) { + return (QEntryElement *) e; + } } } return nil; diff --git a/quickdialog/QEntryValidator.m b/quickdialog/QEntryValidator.m index 108a74d4..133a8cb1 100644 --- a/quickdialog/QEntryValidator.m +++ b/quickdialog/QEntryValidator.m @@ -39,7 +39,7 @@ -(NSString *)validate: (QRootElement *)element } if (_regexPattern) { - NSPredicate *test = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", _regexPattern]; + NSPredicate *test = [NSPredicate predicateWithFormat:@"SELF MATCHES[c] %@", _regexPattern]; if (![test evaluateWithObject: trimmed]) { return _regexFailedText; } diff --git a/quickdialog/QFloatElement.m b/quickdialog/QFloatElement.m index 20273bbb..76e0d590 100644 --- a/quickdialog/QFloatElement.m +++ b/quickdialog/QFloatElement.m @@ -39,10 +39,13 @@ - (void)fetchValueIntoObject:(id)obj { } - (CGFloat)calculateSliderWidth:(QuickDialogTableView *)view cell:(UITableViewCell *)cell { + CGFloat width = view.contentSize.width; + if ( width > 320.0 ) width -= 70.0; if (_title==nil) - return view.contentSize.width-40; - - return view.contentSize.width - [cell.textLabel.text sizeWithFont:[UIFont boldSystemFontOfSize:17]].width - 50; + width -= 40; + else + width -= [cell.textLabel.text sizeWithFont:[UIFont boldSystemFontOfSize:17]].width + 50; + return width; } - (void)valueChanged:(UISlider *)slider { diff --git a/quickdialog/QLabelElement.h b/quickdialog/QLabelElement.h index 051979e4..21468dbb 100644 --- a/quickdialog/QLabelElement.h +++ b/quickdialog/QLabelElement.h @@ -25,8 +25,11 @@ } @property(nonatomic, strong) UIImage *image; +@property(nonatomic, assign) NSString *imageNamed; +@property(nonatomic, assign) UITableViewCellAccessoryType accessoryType; @property(nonatomic, strong) id value; - (QLabelElement *)initWithTitle:(NSString *)string Value:(id)value; + @end \ No newline at end of file diff --git a/quickdialog/QLabelElement.m b/quickdialog/QLabelElement.m index 4380e92f..33c309c4 100644 --- a/quickdialog/QLabelElement.m +++ b/quickdialog/QLabelElement.m @@ -15,10 +15,16 @@ #import "QLabelElement.h" -@implementation QLabelElement +@implementation QLabelElement { +@private + UITableViewCellAccessoryType _accessoryType; +} + @synthesize image = _image; @synthesize value = _value; +@synthesize accessoryType = _accessoryType; + - (QLabelElement *)initWithTitle:(NSString *)title Value:(id)value { self = [super init]; @@ -27,15 +33,27 @@ - (QLabelElement *)initWithTitle:(NSString *)title Value:(id)value { return self; } +-(void)setImageNamed:(NSString *)name { + self.image = [UIImage imageNamed:name]; +} + +- (NSString *)imageNamed { + return nil; +} + + - (UITableViewCell *)getCellForTableView:(QuickDialogTableView *)tableView controller:(QuickDialogController *)controller { - UITableViewCell *cell = [super getCellForTableView:tableView controller:controller]; - cell.accessoryType = UITableViewCellAccessoryNone; + QTableViewCell *cell = (QTableViewCell *) [super getCellForTableView:tableView controller:controller]; + cell.accessoryType = _accessoryType== (int) nil ? UITableViewCellAccessoryNone : _accessoryType; cell.selectionStyle = UITableViewCellSelectionStyleNone; cell.textLabel.text = _title; + cell.textLabel.highlightedTextColor = [UIColor blackColor]; + cell.textLabel.backgroundColor = [UIColor clearColor]; cell.detailTextLabel.text = [_value description]; + cell.detailTextLabel.backgroundColor = [UIColor clearColor]; cell.imageView.image = _image; - cell.accessoryType = self.sections!= nil || self.controllerAction!=nil ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone; + cell.accessoryType = self.sections!= nil || self.controllerAction!=nil ? (_accessoryType != (int) nil ? _accessoryType : UITableViewCellAccessoryDisclosureIndicator) : UITableViewCellAccessoryNone; cell.selectionStyle = self.sections!= nil || self.controllerAction!=nil ? UITableViewCellSelectionStyleBlue: UITableViewCellSelectionStyleNone; return cell; diff --git a/quickdialog/QMultilineElement.h b/quickdialog/QMultilineElement.h new file mode 100644 index 00000000..4608f9a3 --- /dev/null +++ b/quickdialog/QMultilineElement.h @@ -0,0 +1,26 @@ +// +// Copyright 2011 ESCOZ Inc - http://escoz.com +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software distributed under +// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +// ANY KIND, either express or implied. See the License for the specific language governing +// permissions and limitations under the License. +// + + +#import "QElement.h" +#import "QMultilineTextViewController.h" + +@interface QMultilineElement : QEntryElement + +@property(nonatomic, assign) id< QuickDialogEntryElementDelegate> delegate; + + +- (QMultilineElement *)initWithTitle:(NSString *)title value:(NSString *)text; + +@end \ No newline at end of file diff --git a/quickdialog/QMultilineElement.m b/quickdialog/QMultilineElement.m new file mode 100644 index 00000000..0f4444e0 --- /dev/null +++ b/quickdialog/QMultilineElement.m @@ -0,0 +1,72 @@ +// +// Copyright 2011 ESCOZ Inc - http://escoz.com +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software distributed under +// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +// ANY KIND, either express or implied. See the License for the specific language governing +// permissions and limitations under the License. +// + +@implementation QMultilineElement + +@synthesize delegate = _delegate; + + +- (QMultilineElement *)initWithTitle:(NSString *)title value:(NSString *)text +{ + if ((self = [super initWithTitle:title Value:nil])) { + self.textValue = text; + } + return self; +} + +- (UITableViewCell *)getCellForTableView:(QuickDialogTableView *)tableView controller:(QuickDialogController *)controller { + QEntryTableViewCell *cell = (QEntryTableViewCell *) [super getCellForTableView:tableView controller:controller]; + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + cell.selectionStyle = UITableViewCellSelectionStyleBlue; + cell.textField.enabled = NO; + return cell; +} + + +- (void)selected:(QuickDialogTableView *)tableView controller:(QuickDialogController *)controller indexPath:(NSIndexPath *)indexPath +{ + __block QMultilineTextViewController *textController = [[QMultilineTextViewController alloc] initWithTitle:self.title]; + textController.entryElement = self; + textController.entryCell = (QEntryTableViewCell *) [tableView cellForElement:self]; + textController.resizeWhenKeyboardPresented = YES; + textController.textView.text = self.textValue; + textController.textView.autocapitalizationType = self.autocapitalizationType; + textController.textView.autocorrectionType = self.autocorrectionType; + textController.textView.keyboardAppearance = self.keyboardAppearance; + textController.textView.keyboardType = self.keyboardType; + textController.textView.secureTextEntry = self.secureTextEntry; + textController.textView.autocapitalizationType = self.autocapitalizationType; + textController.textView.returnKeyType = self.returnKeyType; + + __block QMultilineElement *weakSelf = self; + textController.willDisappearCallback = ^ { + weakSelf.textValue = textController.textView.text; + [[tableView cellForElement:weakSelf] setNeedsDisplay]; + }; + [controller displayViewController:textController]; +} + +- (void)fetchValueIntoObject:(id)obj +{ + if (_key == nil) { + return; + } + [obj setValue:self.textValue forKey:_key]; +} + +- (BOOL)canTakeFocus { + return NO; +} + +@end diff --git a/quickdialog/QMultilineTextViewController.h b/quickdialog/QMultilineTextViewController.h new file mode 100644 index 00000000..aa8470dd --- /dev/null +++ b/quickdialog/QMultilineTextViewController.h @@ -0,0 +1,36 @@ +// +// Copyright 2011 ESCOZ Inc - http://escoz.com +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software distributed under +// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +// ANY KIND, either express or implied. See the License for the specific language governing +// permissions and limitations under the License. +// + + +#import + +@class QMultilineTextViewController; +@class QMultilineElement; +@class QEntryTableViewCell; + +@interface QMultilineTextViewController : UIViewController + +@property (nonatomic, strong, readonly) UITextView *textView; + +@property(nonatomic, assign) BOOL resizeWhenKeyboardPresented; + +@property(nonatomic, copy) void (^willDisappearCallback)(); + +@property(nonatomic, strong) QMultilineElement *entryElement; + +@property(nonatomic, strong) QEntryTableViewCell *entryCell; + +- (id)initWithTitle:(NSString *)title; + +@end diff --git a/quickdialog/QMultilineTextViewController.m b/quickdialog/QMultilineTextViewController.m new file mode 100644 index 00000000..6f9aa707 --- /dev/null +++ b/quickdialog/QMultilineTextViewController.m @@ -0,0 +1,145 @@ +// +// Copyright 2011 ESCOZ Inc - http://escoz.com +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software distributed under +// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +// ANY KIND, either express or implied. See the License for the specific language governing +// permissions and limitations under the License. +// + + +#import "QuickDialog.h" + +@interface QMultilineTextViewController () + +@end + +@implementation QMultilineTextViewController { + BOOL _viewOnScreen; + BOOL _keyboardVisible; + UITextView* _textView; +} + +@synthesize textView = _textView; +@synthesize resizeWhenKeyboardPresented = _resizeWhenKeyboardPresented; +@synthesize willDisappearCallback = _willDisappearCallback; +@synthesize entryElement = _entryElement; +@synthesize entryCell = _entryCell; + + +- (id)initWithTitle:(NSString *)title +{ + if ((self = [super init])) + { + self.title = (title!=nil) ? title : NSLocalizedString(@"Note", @"Note"); + _textView = [[UITextView alloc] init]; + _textView.delegate = self; + _textView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; + _textView.font = [UIFont systemFontOfSize:18.0f]; + } + return self; +} + +- (void)loadView +{ + self.view = _textView; +} + +- (void)viewWillAppear:(BOOL)animated +{ + _viewOnScreen = YES; + [_textView becomeFirstResponder]; + [super viewWillAppear:animated]; +} + +- (void)viewWillDisappear:(BOOL)animated { + _viewOnScreen = NO; + if (_willDisappearCallback !=nil){ + _willDisappearCallback(); + } + [super viewWillDisappear:animated]; +} + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation +{ + return (interfaceOrientation == UIInterfaceOrientationPortrait); +} + + +- (void) resizeForKeyboard:(NSNotification*)aNotification { + if (!_viewOnScreen) + return; + + BOOL up = aNotification.name == UIKeyboardWillShowNotification; + + if (_keyboardVisible == up) + return; + + _keyboardVisible = up; + NSDictionary* userInfo = [aNotification userInfo]; + NSTimeInterval animationDuration; + UIViewAnimationCurve animationCurve; + CGRect keyboardEndFrame; + [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve]; + [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration]; + [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardEndFrame]; + + [UIView animateWithDuration:animationDuration delay:0 options:animationCurve + animations:^{ + CGRect keyboardFrame = [self.view convertRect:keyboardEndFrame toView:nil]; + _textView.contentInset = UIEdgeInsetsMake(0.0, 0.0, up ? keyboardFrame.size.height : 0, 0.0); + } + completion:NULL]; +} + +- (void)setResizeWhenKeyboardPresented:(BOOL)observesKeyboard { + if (observesKeyboard != _resizeWhenKeyboardPresented) { + _resizeWhenKeyboardPresented = observesKeyboard; + + if (_resizeWhenKeyboardPresented) { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resizeForKeyboard:) name:UIKeyboardWillShowNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resizeForKeyboard:) name:UIKeyboardWillHideNotification object:nil]; + } else { + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil]; + } + } +} + +- (void)textViewDidBeginEditing:(UITextView *)textView { + if(_entryElement && _entryElement.delegate && [_entryElement.delegate respondsToSelector:@selector(QEntryDidBeginEditingElement:andCell:)]){ + [_entryElement.delegate QEntryDidBeginEditingElement:_entryElement andCell:self.entryCell]; + } + +} + +- (void)textViewDidEndEditing:(UITextView *)textView { + _entryElement.textValue = textView.text; + + if(_entryElement && _entryElement.delegate && [_entryElement.delegate respondsToSelector:@selector(QEntryDidEndEditingElement:andCell:)]){ + [_entryElement.delegate QEntryDidEndEditingElement:_entryElement andCell:self.entryCell]; + } +} + +- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { + if(_entryElement && _entryElement.delegate && [_entryElement.delegate respondsToSelector:@selector(QEntryShouldChangeCharactersInRangeForElement:andCell:)]){ + return [_entryElement.delegate QEntryShouldChangeCharactersInRangeForElement:_entryElement andCell:self.entryCell]; + } + return YES; +} + +- (void)textViewDidChange:(UITextView *)textView { + _entryElement.textValue = textView.text; + + if(_entryElement && _entryElement.delegate && [_entryElement.delegate respondsToSelector:@selector(QEntryEditingChangedForElement:andCell:)]){ + [_entryElement.delegate QEntryEditingChangedForElement:_entryElement andCell:self.entryCell]; + } +} + + +@end diff --git a/quickdialog/QPickerElement.h b/quickdialog/QPickerElement.h new file mode 100644 index 00000000..f3347a49 --- /dev/null +++ b/quickdialog/QPickerElement.h @@ -0,0 +1,19 @@ +#import +#import "QEntryElement.h" +#import "QPickerValueParser.h" + +@interface QPickerElement : QEntryElement +{ +@protected + id _valueParser; +} + +@property (nonatomic, strong) id valueParser; +@property (nonatomic, copy) void (^onValueChanged)(void); + +@property (nonatomic, strong) NSArray *items; +@property (nonatomic, readonly) NSArray *selectedIndexes; + +- (QPickerElement *)initWithTitle:(NSString *)title items:(NSArray *)items value:(id)value; + +@end \ No newline at end of file diff --git a/quickdialog/QPickerElement.m b/quickdialog/QPickerElement.m new file mode 100644 index 00000000..64f56898 --- /dev/null +++ b/quickdialog/QPickerElement.m @@ -0,0 +1,67 @@ +#import "QPickerElement.h" +#import "QPickerTableViewCell.h" +#import "QPickerTabDelimitedStringParser.h" + +@implementation QPickerElement +{ +@private + NSArray *_items; + void (^_onValueChanged)(); + + UIPickerView *_pickerView; +} + +@synthesize items = _items; +@synthesize valueParser = _valueParser; +@synthesize onValueChanged = _onValueChanged; + +- (QPickerElement *)init +{ + if (self = [super init]) { + self.valueParser = [QPickerTabDelimitedStringParser new]; + } + return self; +} + +- (QPickerElement *)initWithTitle:(NSString *)title items:(NSArray *)items value:(id)value +{ + if ((self = [super initWithTitle:title Value:value])) { + _items = items; + self.valueParser = [QPickerTabDelimitedStringParser new]; + } + return self; +} + +- (UITableViewCell *)getCellForTableView:(QuickDialogTableView *)tableView controller:(QuickDialogController *)controller +{ + QPickerTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:QPickerTableViewCellIdentifier]; + if (cell == nil) { + cell = [[QPickerTableViewCell alloc] init]; + } + + UIPickerView *pickerView = nil; + [cell prepareForElement:self inTableView:tableView pickerView:&pickerView]; + _pickerView = pickerView; + + cell.imageView.image = self.image; + + return cell; +} + +- (void)fetchValueIntoObject:(id)obj +{ + if (_key != nil) { + [obj setValue:_value forKey:_key]; + } +} + +- (NSArray *)selectedIndexes +{ + NSMutableArray *selectedIndexes = [NSMutableArray arrayWithCapacity:_pickerView.numberOfComponents]; + for (int component = 0; component < _pickerView.numberOfComponents; component++) { + [selectedIndexes addObject:[NSNumber numberWithInteger:[_pickerView selectedRowInComponent:component]]]; + } + return selectedIndexes; +} + +@end \ No newline at end of file diff --git a/quickdialog/QPickerTabDelimitedStringParser.h b/quickdialog/QPickerTabDelimitedStringParser.h new file mode 100644 index 00000000..7559fa05 --- /dev/null +++ b/quickdialog/QPickerTabDelimitedStringParser.h @@ -0,0 +1,13 @@ +// +// QPickerTabDelimitedStringParser.h +// QuickDialog +// +// Created by HiveHicks on 05.04.12. +// + +#import +#import "QPickerValueParser.h" + +@interface QPickerTabDelimitedStringParser : NSObject + +@end diff --git a/quickdialog/QPickerTabDelimitedStringParser.m b/quickdialog/QPickerTabDelimitedStringParser.m new file mode 100644 index 00000000..031faf91 --- /dev/null +++ b/quickdialog/QPickerTabDelimitedStringParser.m @@ -0,0 +1,24 @@ +// +// QPickerTabDelimitedStringParser.m +// QuickDialog +// +// Created by HiveHicks on 05.04.12. +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#import "QPickerTabDelimitedStringParser.h" + +@implementation QPickerTabDelimitedStringParser + +- (id)objectFromComponentsValues:(NSArray *)componentsValues +{ + return [componentsValues componentsJoinedByString:@"\t"]; +} + +- (NSArray *)componentsValuesFromObject:(id)object +{ + NSString *stringValue = [object isKindOfClass:[NSString class]] ? object : [object description]; + return [stringValue componentsSeparatedByString:@"\t"]; +} + +@end diff --git a/quickdialog/QPickerTableViewCell.h b/quickdialog/QPickerTableViewCell.h new file mode 100644 index 00000000..40334629 --- /dev/null +++ b/quickdialog/QPickerTableViewCell.h @@ -0,0 +1,25 @@ +// +// QPickerTableViewCell.h +// QuickDialog +// +// Created by HiveHicks on 05.04.12. +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#import "QEntryTableViewCell.h" + +NSString * const QPickerTableViewCellIdentifier; + +@interface QPickerTableViewCell : QEntryTableViewCell +{ + UIPickerView *_pickerView; +} + +@property (nonatomic, strong) UIPickerView *pickerView; + +- (void)prepareForElement:(QEntryElement *)element inTableView:(QuickDialogTableView *)tableView pickerView:(UIPickerView **)pickerView; + +- (void)setPickerViewValue:(id)value; +- (id)getPickerViewValue; + +@end diff --git a/quickdialog/QPickerTableViewCell.m b/quickdialog/QPickerTableViewCell.m new file mode 100644 index 00000000..9a0e4eb1 --- /dev/null +++ b/quickdialog/QPickerTableViewCell.m @@ -0,0 +1,150 @@ +// +// QPickerTableViewCell.m +// QuickDialog +// +// Created by HiveHicks on 05.04.12. +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#import "QPickerTableViewCell.h" + +NSString * const QPickerTableViewCellIdentifier = @"QPickerTableViewCell"; + +@interface QPickerTableViewCell () +@property (nonatomic, readonly) QPickerElement *pickerElement; +@end + +@implementation QPickerTableViewCell + +@synthesize pickerView = _pickerView; + +- (QPickerTableViewCell *)init +{ + if ((self = [self initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:QPickerTableViewCellIdentifier])) + { + [self createSubviews]; + self.selectionStyle = UITableViewCellSelectionStyleBlue; + } + + return self; +} + +- (void)createSubviews +{ + [super createSubviews]; + _textField.hidden = YES; +} + +- (QPickerElement *)pickerElement +{ + return (QPickerElement *)_entryElement; +} + +- (void)textFieldDidEndEditing:(UITextField *)textField +{ + [super textFieldDidEndEditing:textField]; + self.selected = NO; +} + +- (void)textFieldDidBeginEditing:(UITextField *)textField +{ + [_pickerView sizeToFit]; + + _textField.inputView = _pickerView; + + if (self.pickerElement.value != nil) { + [self setPickerViewValue:self.pickerElement.value]; + } + + [super textFieldDidBeginEditing:textField]; + self.selected = YES; +} + +- (void)prepareForElement:(QEntryElement *)element inTableView:(QuickDialogTableView *)tableView pickerView:(UIPickerView **)pickerView +{ + [self prepareForElement:element inTableView:tableView]; + + _pickerView = [[UIPickerView alloc] init]; + _pickerView.showsSelectionIndicator = YES; + _pickerView.dataSource = self; + _pickerView.delegate = self; + + *pickerView = _pickerView; +} + +- (void)prepareForElement:(QEntryElement *)element inTableView:(QuickDialogTableView *)tableView +{ + [super prepareForElement:element inTableView:tableView]; + + QPickerElement *pickerElement = (QPickerElement *)element; + + if ([pickerElement.valueParser respondsToSelector:@selector(presentationOfObject:)]) { + self.detailTextLabel.text = [pickerElement.valueParser presentationOfObject:pickerElement.value]; + _textField.text = [pickerElement.valueParser presentationOfObject:pickerElement.value]; + } else { + self.detailTextLabel.text = [pickerElement.value description]; + _textField.text = [pickerElement.value description]; + } + + [self setNeedsDisplay]; +} + +#pragma mark - UIPickerView data source and delegate + +- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView +{ + return self.pickerElement.items.count; +} + +- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component +{ + return [[self.pickerElement.items objectAtIndex:(NSUInteger) component] count]; +} + +- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component +{ + return [[[self.pickerElement.items objectAtIndex:(NSUInteger) component] objectAtIndex:(NSUInteger) row] description]; +} + +- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component +{ + self.pickerElement.value = [self getPickerViewValue]; + [self prepareForElement:_entryElement inTableView:_quickformTableView]; + if (self.pickerElement.onValueChanged != nil) { + self.pickerElement.onValueChanged(); + } +} + +#pragma mark - Getting/setting value from UIPickerView + +- (id)getPickerViewValue +{ + NSMutableArray *componentsValues = [NSMutableArray array]; + + for (int i = 0; i < _pickerView.numberOfComponents; i++) + { + NSInteger rowIndex = [_pickerView selectedRowInComponent:i]; + if (rowIndex >= 0) { + [componentsValues addObject:[self pickerView:_pickerView titleForRow:rowIndex forComponent:i]]; + } else { + [componentsValues addObject:[NSNull null]]; + } + } + + NSLog(@"AA%@", [self.pickerElement.valueParser objectFromComponentsValues:componentsValues]); + return [self.pickerElement.valueParser objectFromComponentsValues:componentsValues]; +} + +- (void)setPickerViewValue:(id)value +{ + NSArray *componentsValues = [self.pickerElement.valueParser componentsValuesFromObject:value]; + + for (int componentIndex = 0; componentIndex < componentsValues.count && _pickerView.numberOfComponents; componentIndex++) + { + id componentValue = [componentsValues objectAtIndex:(NSUInteger) componentIndex]; + NSInteger rowIndex = [[self.pickerElement.items objectAtIndex:componentIndex] indexOfObject:componentValue]; + [_pickerView selectRow:rowIndex inComponent:componentIndex animated:YES]; + } +} + +@end \ No newline at end of file diff --git a/quickdialog/QPickerValueParser.h b/quickdialog/QPickerValueParser.h new file mode 100644 index 00000000..0b0ccbf8 --- /dev/null +++ b/quickdialog/QPickerValueParser.h @@ -0,0 +1,19 @@ +// +// QPickerValueExtrator.h +// QuickDialog +// +// Created by HiveHicks on 05.04.12. +// + +#import + +@protocol QPickerValueParser + +@required +- (id)objectFromComponentsValues:(NSArray *)componentsValues; +- (NSArray *)componentsValuesFromObject:(id)object; + +@optional +- (NSString *)presentationOfObject:(id)object; + +@end diff --git a/quickdialog/QRadioElement.h b/quickdialog/QRadioElement.h index 2b668d6f..f10ecc15 100644 --- a/quickdialog/QRadioElement.h +++ b/quickdialog/QRadioElement.h @@ -14,16 +14,24 @@ #import "QuickDialogTableView.h" -@interface QRadioElement : QRootElement { +@interface QRadioElement : QEntryElement { NSArray *_items; NSArray *_values; NSInteger _selected; } @property(nonatomic, retain) NSArray *items; +@property(nonatomic, assign) id selectedItem; @property(nonatomic, assign, readwrite) NSInteger selected; @property(nonatomic, retain) NSArray *values; +- (QRadioElement *)initWithDict:(NSDictionary *)valuesDictionary selected:(int)selected title:(NSString *)title; + +- (void)createElements; + +- (NSObject *)selectedValue; +- (void)setSelectedValue:(NSObject *)aSelected; + - (QRadioElement *)initWithItems:(NSArray *)stringArray selected:(NSInteger)selected; - (QRadioElement *)initWithItems:(NSArray *)stringArray selected:(NSInteger)selected title:(NSString *)title; @end \ No newline at end of file diff --git a/quickdialog/QRadioElement.m b/quickdialog/QRadioElement.m index 78d0ee1a..ae246f91 100644 --- a/quickdialog/QRadioElement.m +++ b/quickdialog/QRadioElement.m @@ -12,6 +12,8 @@ // permissions and limitations under the License. // +#import "QBindingEvaluator.h" + @implementation QRadioElement { QSection *_internalRadioItemsSection; } @@ -25,6 +27,7 @@ - (void)createElements { _sections = nil; _internalRadioItemsSection = [[QSection alloc] init]; _parentSection = _internalRadioItemsSection; + _grouped = YES; [self addSection:_parentSection]; @@ -38,12 +41,46 @@ -(void)setItems:(NSArray *)items { [self createElements]; } +-(NSObject *)selectedValue { + return [_values objectAtIndex:(NSUInteger) _selected]; +} + +-(void)setSelectedValue:(NSObject *)aSelected { + if ([aSelected isKindOfClass:[NSNumber class]]) { + _selected = [(NSNumber *)aSelected integerValue]; + } else { + _selected = [_values indexOfObject:aSelected]; + } +} + - (QRadioElement *)initWithItems:(NSArray *)stringArray selected:(NSInteger)selected { self = [self initWithItems:stringArray selected:selected title:nil]; return self; } + +- (QRadioElement *)initWithDict:(NSDictionary *)valuesDictionary selected:(int)selected title:(NSString *)title { + self = [self initWithItems:valuesDictionary.allKeys selected:(NSUInteger) selected]; + _values = valuesDictionary.allValues; + self.title = title; + return self; +} + + +-(void)setSelectedItem:(id)item { + if (self.items==nil) + return; + self.selected = [self.items indexOfObject:item]; +} + +-(id)selectedItem { + if (self.items == nil || [self.items count]= 0 && _selected <_items.count) selectedValue = [[_items objectAtIndex:(NSUInteger) _selected] description]; if (self.title == NULL){ - cell.textLabel.text = selectedValue; + cell.textField.text = selectedValue; cell.detailTextLabel.text = nil; cell.imageView.image = nil; } else { cell.textLabel.text = _title; - cell.detailTextLabel.text = selectedValue; + cell.textField.text = selectedValue; cell.imageView.image = nil; } + cell.textLabel.highlightedTextColor = [UIColor blackColor]; + cell.textField.textAlignment = UITextAlignmentRight; + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + cell.selectionStyle = UITableViewCellSelectionStyleBlue; + cell.textField.userInteractionEnabled = NO; return cell; } +-(void)setSelected:(NSInteger)aSelected { + _selected = aSelected; + +} + - (void)fetchValueIntoObject:(id)obj { if (_key==nil) return; @@ -95,6 +142,8 @@ - (void)fetchValueIntoObject:(id)obj { } } - +- (BOOL)canTakeFocus { + return NO; +} @end diff --git a/quickdialog/QRadioItemElement.m b/quickdialog/QRadioItemElement.m index 549f87d0..3d121753 100644 --- a/quickdialog/QRadioItemElement.m +++ b/quickdialog/QRadioItemElement.m @@ -57,10 +57,9 @@ - (void)selected:(QuickDialogTableView *)tableView controller:(QuickDialogContro selectedCell.accessoryType = UITableViewCellAccessoryCheckmark; } - if (_radioElement!= nil){ + if (_radioElement!= nil) + { _radioElement.selected = _index; - - [_radioElement handleElementSelected:controller]; tableView.userInteractionEnabled = NO; @@ -70,9 +69,15 @@ - (void)selected:(QuickDialogTableView *)tableView controller:(QuickDialogContro userInfo:nil repeats:NO]; - } else if (_radioSection!=nil){ + } + else if (_radioSection!=nil) + { [tableView deselectRowAtIndexPath:indexPath animated:YES]; + _radioSection.selected = _index; + if (_radioSection.onSelected) { + _radioSection.onSelected(); + } } } diff --git a/quickdialog/QRadioSection.h b/quickdialog/QRadioSection.h index 6974906f..bffaca57 100644 --- a/quickdialog/QRadioSection.h +++ b/quickdialog/QRadioSection.h @@ -13,21 +13,10 @@ // #import "QSection.h" +#import "QSelectSection.h" -@interface QRadioSection : QSection { +@interface QRadioSection : QSelectSection -@protected - NSArray *_items; - NSInteger _selected; -} - -@property(nonatomic, strong) NSArray *items; @property(nonatomic) NSInteger selected; - -- (QRadioSection *)initWithItems:(NSArray *)stringArray selected:(NSUInteger)selected; - -- (QRadioSection *)initWithItems:(NSArray *)stringArray selected:(NSUInteger)selected title:(NSString *)title; - - @end \ No newline at end of file diff --git a/quickdialog/QRadioSection.m b/quickdialog/QRadioSection.m index 8a4bcc07..36e0bc6b 100644 --- a/quickdialog/QRadioSection.m +++ b/quickdialog/QRadioSection.m @@ -19,47 +19,14 @@ @implementation QRadioSection -@synthesize selected = _selected; - - -- (void)createElements { - - for (NSUInteger i=0; i< [_items count]; i++){ - [self addElement:[[QRadioItemElement alloc] initWithIndex:i RadioSection:self]]; - } -} - -- (NSArray *)items { - return _items; -} - -- (void)setItems:(NSArray *)items { - _items = items; - self.elements = nil; - [self createElements]; -} - -- (QRadioSection *)initWithItems:(NSArray *)stringArray selected:(NSUInteger)selected { - self = [super init]; - if (self!=nil){ - _items = stringArray; - _selected = selected; - [self createElements]; - } - return self; +- (NSInteger)selected +{ + return [[self.selectedIndexes objectAtIndex:0] unsignedIntegerValue]; } -- (QRadioSection *)initWithItems:(NSArray *)stringArray selected:(NSUInteger)selected title:(NSString *)title { - self = [self initWithItems:stringArray selected:selected]; - self.title = title; - return self; +- (void)setSelected:(NSInteger)selected +{ + [self.selectedIndexes replaceObjectAtIndex:0 withObject:[NSNumber numberWithUnsignedInteger:selected]]; } -- (void)fetchValueIntoObject:(id)obj { - if (_key==nil) - return; - [obj setValue:[NSNumber numberWithInteger:_selected] forKey:_key]; -} - - @end \ No newline at end of file diff --git a/quickdialog/QRootBuilder.h b/quickdialog/QRootBuilder.h index 3db02b7b..15020427 100644 --- a/quickdialog/QRootBuilder.h +++ b/quickdialog/QRootBuilder.h @@ -19,11 +19,14 @@ } -- (QRootElement *)buildSectionsWithObject:(id)obj; +- (QRootElement *)buildWithObject:(id)obj; -+ (void)trySetProperty:(NSString *)propertyName onObject:(id)target withValue:(id)value; ++ (void)trySetProperty:(NSString *)propertyName onObject:(id)target withValue:(id)value localized:(BOOL)shouldLocalize; - (QElement *)buildElementWithObject:(id)obj; +- (void)buildSectionWithObject:(id)obj forRoot:(QRootElement *)root; + +- (QSection *)buildSectionWithObject:(NSDictionary *)dictionary; @end \ No newline at end of file diff --git a/quickdialog/QRootBuilder.m b/quickdialog/QRootBuilder.m index d412e83e..0bf775ec 100644 --- a/quickdialog/QRootBuilder.m +++ b/quickdialog/QRootBuilder.m @@ -12,6 +12,7 @@ // permissions and limitations under the License. // + NSDictionary *QRootBuilderStringToTypeConversionDict; @interface QRootBuilder () @@ -23,18 +24,40 @@ - (void)initializeMappings; @implementation QRootBuilder -+ (void)trySetProperty:(NSString *)propertyName onObject:(id)target withValue:(id)value { ++ (void)trySetProperty:(NSString *)propertyName onObject:(id)target withValue:(id)value localized:(BOOL)shouldLocalize{ + shouldLocalize = shouldLocalize && ![propertyName isEqualToString:@"bind"] && ![propertyName isEqualToString:@"type"]; if ([value isKindOfClass:[NSString class]]) { - [target setValue:value forKeyPath:propertyName]; if ([QRootBuilderStringToTypeConversionDict objectForKey:propertyName]!=nil) { [target setValue:[[QRootBuilderStringToTypeConversionDict objectForKey:propertyName] objectForKey:value] forKeyPath:propertyName]; + } else { + [target setValue:shouldLocalize ? QTranslate(value) : value forKeyPath:propertyName]; } } else if ([value isKindOfClass:[NSNumber class]]){ [target setValue:value forKeyPath:propertyName]; } else if ([value isKindOfClass:[NSArray class]]) { - [target setValue:value forKeyPath:propertyName]; + + NSUInteger i= 0; + NSMutableArray * itemsTranslated = [(NSArray *) value mutableCopy]; + + if (shouldLocalize){ + for (id obj in (NSArray *)value){ + if ([obj isKindOfClass:[NSString class]]){ + @try { + [itemsTranslated replaceObjectAtIndex:i withObject:QTranslate(obj)]; + } + @catch (NSException * e) { + NSLog(@"Exception: %@", e); + } + } + i++; + } + } + + [target setValue:itemsTranslated forKeyPath:propertyName]; } else if ([value isKindOfClass:[NSDictionary class]]){ [target setValue:value forKeyPath:propertyName]; + } else if ([value isKindOfClass:[NSObject class]]){ + [target setValue:value forKeyPath:propertyName]; } else if (value == nil){ [target setValue:nil forKeyPath:propertyName]; } @@ -46,7 +69,7 @@ - (void)updateObject:(id)element withPropertiesFrom:(NSDictionary *)dict { continue; id value = [dict valueForKey:key]; - [QRootBuilder trySetProperty:key onObject:element withValue:value]; + [QRootBuilder trySetProperty:key onObject:element withValue:value localized:YES]; } } @@ -64,6 +87,17 @@ - (QElement *)buildElementWithObject:(id)obj { return element; } +- (QSection *)buildSectionWithObject:(NSDictionary *)obj { + QSection *sect = nil; + if ([obj valueForKey:[NSString stringWithFormat:@"type"]]!=nil){ + sect = [[NSClassFromString([obj valueForKey:[NSString stringWithFormat:@"type"]]) alloc] init]; + } else { + sect = [[QSection alloc] init]; + } + [self updateObject:sect withPropertiesFrom:obj]; + return sect; +} + - (void)buildSectionWithObject:(id)obj forRoot:(QRootElement *)root { QSection *sect = nil; if ([obj valueForKey:[NSString stringWithFormat:@"type"]]!=nil){ @@ -78,7 +112,7 @@ - (void)buildSectionWithObject:(id)obj forRoot:(QRootElement *)root { } } -- (QRootElement *)buildSectionsWithObject:(id)obj { +- (QRootElement *)buildWithObject:(id)obj { if (QRootBuilderStringToTypeConversionDict ==nil) [self initializeMappings]; @@ -107,6 +141,13 @@ - (void)initializeMappings { [NSNumber numberWithInt:UITextAutocorrectionTypeYes], @"Yes", nil], @"autocorrectionType", + [[NSDictionary alloc] initWithObjectsAndKeys: + [NSNumber numberWithInt:UITableViewCellStyleDefault], @"Default", + [NSNumber numberWithInt:UITableViewCellStyleSubtitle], @"Subtitle", + [NSNumber numberWithInt:UITableViewCellStyleValue2], @"Value2", + [NSNumber numberWithInt:UITableViewCellStyleValue1], @"Value1", + nil], @"cellStyle", + [[NSDictionary alloc] initWithObjectsAndKeys: [NSNumber numberWithInt:UIKeyboardTypeDefault], @"Default", [NSNumber numberWithInt:UIKeyboardTypeASCIICapable], @"ASCIICapable", @@ -132,6 +173,20 @@ - (void)initializeMappings { [NSNumber numberWithInt:UIActivityIndicatorViewStyleWhiteLarge], @"WhiteLarge", nil], @"indicatorViewStyle", + [[NSDictionary alloc] initWithObjectsAndKeys: + [NSNumber numberWithInt:UITableViewCellAccessoryDetailDisclosureButton], @"DetailDisclosureButton", + [NSNumber numberWithInt:UITableViewCellAccessoryCheckmark], @"Checkmark", + [NSNumber numberWithInt:UITableViewCellAccessoryDisclosureIndicator], @"DisclosureIndicator", + [NSNumber numberWithInt:UITableViewCellAccessoryNone], @"None", + nil], @"accessoryType", + + [[NSDictionary alloc] initWithObjectsAndKeys: + [NSNumber numberWithInt:UIDatePickerModeDate], @"Date", + [NSNumber numberWithInt:UIDatePickerModeTime], @"Time", + [NSNumber numberWithInt:UIDatePickerModeDateAndTime], @"DateAndTime", + [NSNumber numberWithInt:UIDatePickerModeCountDownTimer], @"CountDownTimer", + nil], @"mode", + [[NSDictionary alloc] initWithObjectsAndKeys: [NSNumber numberWithInt:UIReturnKeyDefault], @"Default", [NSNumber numberWithInt:UIReturnKeyGo], @"Go", @@ -146,6 +201,10 @@ - (void)initializeMappings { [NSNumber numberWithInt:UIReturnKeyEmergencyCall], @"EmergencyCall", nil], @"returnKeyType", + [[NSDictionary alloc] initWithObjectsAndKeys: + [NSNumber numberWithInt:QLabelingPolicyTrimTitle], @"trimTitle", + [NSNumber numberWithInt:QLabelingPolicyTrimValue], @"trimValue", + nil], @"labelingPolicy", nil]; } diff --git a/quickdialog/QRootElement+Builder.h b/quickdialog/QRootElement+JsonBuilder.h similarity index 90% rename from quickdialog/QRootElement+Builder.h rename to quickdialog/QRootElement+JsonBuilder.h index f9c1e350..9cc8d2da 100644 --- a/quickdialog/QRootElement+Builder.h +++ b/quickdialog/QRootElement+JsonBuilder.h @@ -16,10 +16,12 @@ #import "QRootElement.h" -@interface QRootElement (Builder) +@interface QRootElement (JsonBuilder) - (QRootElement *)initWithJSONFile:(NSString *)json andData:(id)data; +- (QRootElement *)initWithJSON:(id)parsedJson andData:(id)data; + - (QRootElement *)initWithJSONFile:(NSString *)jsonPath andDataJSONFile:(NSString *)dataPath; + (QRootElement *)rootForJSON:(NSString *)json; diff --git a/quickdialog/QRootElement+Builder.m b/quickdialog/QRootElement+JsonBuilder.m similarity index 90% rename from quickdialog/QRootElement+Builder.m rename to quickdialog/QRootElement+JsonBuilder.m index 98727ba1..ed90ba09 100644 --- a/quickdialog/QRootElement+Builder.m +++ b/quickdialog/QRootElement+JsonBuilder.m @@ -16,7 +16,7 @@ #import #import "QRootBuilder.h" -@implementation QRootElement (Builder) +@implementation QRootElement (JsonBuilder) - (QRootElement *)initWithJSONFile:(NSString *)jsonPath { @@ -36,14 +36,18 @@ - (QRootElement *)initWithJSONFile:(NSString *)jsonPath andData:(id)data { NSString *filePath = [[NSBundle mainBundle] pathForResource:jsonPath ofType:@"json"]; NSDictionary *jsonRoot = [JSONSerialization JSONObjectWithData:[NSData dataWithContentsOfFile:filePath] options:0 error:&jsonParsingError]; - self = [[QRootBuilder new] buildSectionsWithObject:jsonRoot]; + self = [self initWithJSON:jsonRoot andData:data]; + return self; +} + +- (QRootElement *)initWithJSON:(id)jsonRoot andData:(id)data { + + self = [[QRootBuilder new] buildWithObject:jsonRoot]; if (data!=nil) [self bindToObject:data]; - return self; } - - (QRootElement *)initWithJSONFile:(NSString *)jsonPath andDataJSONFile:(NSString *)dataPath { Class JSONSerialization = [QRootElement JSONParserClass]; NSAssert(JSONSerialization != NULL, @"No JSON serializer available!"); diff --git a/quickdialog/QRootElement.h b/quickdialog/QRootElement.h index daf1414c..560c9e69 100644 --- a/quickdialog/QRootElement.h +++ b/quickdialog/QRootElement.h @@ -27,11 +27,14 @@ @property(nonatomic, retain) NSString *title; @property(nonatomic, strong) NSMutableArray *sections; +@property(nonatomic, strong) NSDictionary *sectionTemplate; @property(assign) BOOL grouped; @property(nonatomic, retain) NSString *controllerName; +@property(nonatomic, copy) NSString *emptyMessage; + - (QRootElement *)init; - (void)addSection:(QSection *)section; @@ -39,5 +42,10 @@ - (NSInteger)numberOfSections; +- (void)fetchValueIntoObject:(id)obj; + +- (void)fetchValueUsingBindingsIntoObject:(id)object; + +- (QSection *)sectionWithKey:(NSString *)key; - (QElement *)elementWithKey:(NSString *)string; @end \ No newline at end of file diff --git a/quickdialog/QRootElement.m b/quickdialog/QRootElement.m index 4b47d0e0..5c36f0d6 100644 --- a/quickdialog/QRootElement.m +++ b/quickdialog/QRootElement.m @@ -12,12 +12,21 @@ // permissions and limitations under the License. // -@implementation QRootElement +#import "QBindingEvaluator.h" + +@implementation QRootElement { +@private + NSDictionary *_sectionTemplate; +} + @synthesize title = _title; @synthesize sections = _sections; @synthesize grouped = _grouped; @synthesize controllerName = _controllerName; +@synthesize sectionTemplate = _sectionTemplate; +@synthesize emptyMessage = _emptyMessage; + - (QRootElement *)init { self = [super init]; @@ -43,7 +52,8 @@ - (UITableViewCell *)getCellForTableView:(QuickDialogTableView *)tableView contr UITableViewCell *cell = [super getCellForTableView:tableView controller:controller]; cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; cell.selectionStyle = UITableViewCellSelectionStyleBlue; - cell.textLabel.text = _title; + if (_title!= nil) + cell.textLabel.text = _title; return cell; } @@ -58,18 +68,28 @@ - (void)selected:(QuickDialogTableView *)tableView controller:(QuickDialogContro - (void)fetchValueIntoObject:(id)obj { for (QSection *s in _sections){ - for (QElement *el in s.elements) { - [el fetchValueIntoObject:obj]; - } + [s fetchValueIntoObject:obj]; + } } -- (void)bindToObject:(id)obj { +- (void)fetchValueUsingBindingsIntoObject:(id)obj { for (QSection *s in _sections){ - [s bindToObject:obj]; + [s fetchValueUsingBindingsIntoObject:obj]; + } + [super fetchValueUsingBindingsIntoObject:obj]; +} + +- (void)bindToObject:(id)data { + if ([self.bind length]==0 || [self.bind rangeOfString:@"iterate"].location == NSNotFound) { + for (QSection *sections in self.sections) { + [sections bindToObject:data]; + } + } else { + [self.sections removeAllObjects]; } - [super bindToObject:obj]; + [[QBindingEvaluator new] bindObject:self toData:data]; } @@ -88,6 +108,15 @@ -(void)dealloc { } } +- (QSection *)sectionWithKey:(NSString *)key +{ + for (QSection *section in _sections) { + if ([section.key isEqualToString:key]) { + return section; + } + } + return nil; +} - (QElement *)elementWithKey:(NSString *)elementKey { for (QSection *s in _sections){ diff --git a/quickdialog/QSection.h b/quickdialog/QSection.h index d8393c25..7a7b4e60 100644 --- a/quickdialog/QSection.h +++ b/quickdialog/QSection.h @@ -51,10 +51,16 @@ @property(nonatomic, strong) NSDictionary *elementTemplate; +@property(nonatomic, assign) BOOL canDeleteRows; + - (QSection *)initWithTitle:(NSString *)string; + - (void)addElement:(QElement *)element; -- (void)fetchValueIntoObject:(id)obj; +- (void)insertElement:(QElement *)element atIndex:(NSUInteger)index; +- (NSUInteger)indexOfElement:(QElement *)element; - (void)bindToObject:(id)data; -(void)validate:(NSMutableArray *)errors; +- (void)fetchValueIntoObject:(id)obj; +- (void)fetchValueUsingBindingsIntoObject:(id)data; @end \ No newline at end of file diff --git a/quickdialog/QSection.m b/quickdialog/QSection.m index 04d69ad1..0ea0ba81 100644 --- a/quickdialog/QSection.m +++ b/quickdialog/QSection.m @@ -19,6 +19,7 @@ @implementation QSection { NSString *_headerImage; NSString *_footerImage; NSDictionary *_elementTemplate; + BOOL _canDeleteRows; } @synthesize title; @synthesize footer; @@ -32,6 +33,7 @@ @implementation QSection { @synthesize headerImage = _headerImage; @synthesize footerImage = _footerImage; @synthesize elementTemplate = _elementTemplate; +@synthesize canDeleteRows = _canDeleteRows; - (BOOL)needsEditing { @@ -58,12 +60,32 @@ - (QSection *)initWithTitle:(NSString *)sectionTitle { return self; } -- (void)addElement:(QElement *)element { - if (self.elements==nil) - self.elements = [[NSMutableArray alloc] init]; - +- (void)addElement:(QElement *)element +{ + if (self.elements == nil) { + self.elements = [NSMutableArray array]; + } + + element.parentSection = self; [self.elements addObject:element]; +} + +- (void)insertElement:(QElement *)element atIndex:(NSUInteger)index +{ + if (self.elements == nil) { + self.elements = [NSMutableArray array]; + } + element.parentSection = self; + [self.elements insertObject:element atIndex:index]; +} + +- (NSUInteger)indexOfElement:(QElement *)element +{ + if (self.elements) { + return [self.elements indexOfObject:element]; + } + return NSNotFound; } - (void)fetchValueIntoObject:(id)obj { @@ -79,17 +101,15 @@ - (void)dealloc { } - (void)bindToObject:(id)data { - if ([self.bind length]==0 || [self.bind rangeOfString:@"iterate"].location == NSNotFound) { - - for (QElement *el in self.elements) { - [el bindToObject:data]; + for (QElement *el in self.elements) { + [el bindToObject:data]; + } + } else { + [self.elements removeAllObjects]; } - } else { - [self.elements removeAllObjects]; - } - [[QBindingEvaluator new] bindObject:self toData:data]; + [[QBindingEvaluator new] bindObject:self toData:data]; } @@ -100,4 +120,10 @@ -(void)validate: (NSMutableArray *)errors } } +- (void)fetchValueUsingBindingsIntoObject:(id)data { + for (QElement *el in self.elements) { + [el fetchValueUsingBindingsIntoObject:data]; + } + +} @end \ No newline at end of file diff --git a/quickdialog/QSegmentedElement.h b/quickdialog/QSegmentedElement.h new file mode 100644 index 00000000..aea61361 --- /dev/null +++ b/quickdialog/QSegmentedElement.h @@ -0,0 +1,18 @@ +// +// Created by escoz on 1/15/12. +// + +#import + + +@interface QSegmentedElement : QRadioElement { + +} +- (QSegmentedElement *)initWithItems:(NSArray *)stringArray selected:(NSInteger)selected; + +- (QSegmentedElement *)initWithItems:(NSArray *)stringArray selected:(NSInteger)selected title:(NSString *)title; + +- (QSegmentedElement *)init; + + +@end \ No newline at end of file diff --git a/quickdialog/QSegmentedElement.m b/quickdialog/QSegmentedElement.m new file mode 100644 index 00000000..7440cfa0 --- /dev/null +++ b/quickdialog/QSegmentedElement.m @@ -0,0 +1,57 @@ +// +// Created by escoz on 1/15/12. +// +#import "QSegmentedElement.h" + +@implementation QSegmentedElement { + QuickDialogController *_controller; +} +- (void)setItems:(NSArray *)anItems { + if (_items != anItems) { + _items = anItems; + } +} + +- (QSegmentedElement *)initWithItems:(NSArray *)stringArray selected:(NSInteger)selected { + self = [super initWithItems:stringArray selected:selected]; + return self; +} + +- (QSegmentedElement *)initWithItems:(NSArray *)stringArray selected:(NSInteger)selected title:(NSString *)title { + self = [super initWithItems:stringArray selected:selected title:title]; + return self; +} + +- (QSegmentedElement *)init { + self = [super init]; + return self; +} + +- (void)handleSegmentedControlValueChanged:(id)control { + _selected = ((UISegmentedControl *)control).selectedSegmentIndex; + [self handleElementSelected:_controller]; +} + +- (UITableViewCell *)getCellForTableView:(QuickDialogTableView *)tableView controller:(QuickDialogController *)controller { + _controller = controller; + QTableViewCell *cell = [[QTableViewCell alloc] init]; + cell.backgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)]; + cell.backgroundColor = [UIColor clearColor]; + UISegmentedControl *control = [[UISegmentedControl alloc] initWithItems:_items]; + [control addTarget:self action:@selector(handleSegmentedControlValueChanged:) forControlEvents:UIControlEventValueChanged]; + const BOOL isPhone = [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone; + control.frame = CGRectMake(isPhone ? 9 : 30, 0, isPhone ? 302 : 260, 46); + control.autoresizingMask = UIViewAutoresizingFlexibleWidth; + control.segmentedControlStyle = UISegmentedControlStyleBar; + control.selectedSegmentIndex = _selected; + control.tag = 4321; + + [cell addSubview:control]; + return cell; +} + +- (BOOL)canTakeFocus { + return NO; +} + +@end \ No newline at end of file diff --git a/quickdialog/QSelectItemElement.h b/quickdialog/QSelectItemElement.h new file mode 100644 index 00000000..4dffb237 --- /dev/null +++ b/quickdialog/QSelectItemElement.h @@ -0,0 +1,22 @@ +// +// QSelectItemElement.h +// QuickDialog +// +// Created by HiveHicks on 23.03.12. +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#import "QLabelElement.h" +#import "QuickDialogTableView.h" +#import "QLabelElement.h" +#import "QSelectSection.h" + +@interface QSelectItemElement : QLabelElement +{ + NSUInteger _index; + QSelectSection *_selectSection; +} + +- (QSelectItemElement *)initWithIndex:(NSUInteger)integer selectSection:(QSelectSection *)section; + +@end diff --git a/quickdialog/QSelectItemElement.m b/quickdialog/QSelectItemElement.m new file mode 100644 index 00000000..3f5c0bcf --- /dev/null +++ b/quickdialog/QSelectItemElement.m @@ -0,0 +1,80 @@ +// +// QSelectItemElement.m +// QuickDialog +// +// Created by HiveHicks on 23.03.12. +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#import "QSelectItemElement.h" + +@implementation QSelectItemElement + +- (QSelectItemElement *)initWithIndex:(NSUInteger)index selectSection:(QSelectSection *)section +{ + if (self = [super init]) { + _selectSection = section; + _index = index; + _title = [[_selectSection.items objectAtIndex:_index] description]; + } + return self; +} + +- (UITableViewCell *)getCellForTableView:(QuickDialogTableView *)tableView controller:(QuickDialogController *)controller +{ + UITableViewCell *cell = [super getCellForTableView:tableView controller:controller]; + cell.selectionStyle = UITableViewCellSelectionStyleBlue; + cell.accessoryType = + [_selectSection.selectedIndexes containsObject:[NSNumber numberWithUnsignedInteger:_index]] + ? UITableViewCellAccessoryCheckmark + : UITableViewCellAccessoryNone; + + return cell; +} + +- (void)selected:(QuickDialogTableView *)tableView controller:(QuickDialogController *)controller indexPath:(NSIndexPath *)indexPath +{ + [super selected:tableView controller:controller indexPath:indexPath]; + + NSNumber *numberIndex = [NSNumber numberWithUnsignedInteger:_index]; + UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath]; + + if (_selectSection.multipleAllowed) + { + if ([_selectSection.selectedIndexes containsObject:numberIndex]) { + selectedCell.accessoryType = UITableViewCellAccessoryNone; + [_selectSection.selectedIndexes removeObject:numberIndex]; + } else { + selectedCell.accessoryType = UITableViewCellAccessoryCheckmark; + [_selectSection.selectedIndexes addObject:numberIndex]; + } + } + else + { + if (![_selectSection.selectedIndexes containsObject:numberIndex]) + { + NSNumber *oldCellRowNumber = [_selectSection.selectedIndexes count] > 0 ? [_selectSection.selectedIndexes objectAtIndex:0] : nil; + if (oldCellRowNumber) + { + UITableViewCell *oldCell = [tableView cellForRowAtIndexPath: + [NSIndexPath indexPathForRow:[oldCellRowNumber unsignedIntegerValue] + inSection:indexPath.section]]; + + oldCell.accessoryType = UITableViewCellAccessoryNone; + [_selectSection.selectedIndexes removeObject:oldCellRowNumber]; + [oldCell setNeedsDisplay]; + } + + selectedCell.accessoryType = UITableViewCellAccessoryCheckmark; + [_selectSection.selectedIndexes addObject:numberIndex]; + } + } + + if (_selectSection.onSelected) { + _selectSection.onSelected(); + } + + [tableView deselectRowAtIndexPath:indexPath animated:YES]; +} + +@end diff --git a/quickdialog/QSelectSection.h b/quickdialog/QSelectSection.h new file mode 100644 index 00000000..a7bf09d2 --- /dev/null +++ b/quickdialog/QSelectSection.h @@ -0,0 +1,36 @@ +// +// QSelectSection.h +// QuickDialog +// +// Created by HiveHicks on 23.03.12. +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#import "QSection.h" + +@interface QSelectSection : QSection +{ + NSMutableArray *_items; +} + +@property(nonatomic, strong) NSArray *items; +@property (nonatomic, strong) NSMutableArray *selectedIndexes; +@property (nonatomic, readonly) NSArray *selectedItems; + +@property (nonatomic) BOOL multipleAllowed; + +@property(nonatomic, copy) void (^onSelected)(void); + +- (id)initWithItems:(NSArray *)stringArray selectedIndexes:(NSArray *)selected; +- (id)initWithItems:(NSArray *)stringArray selectedIndexes:(NSArray *)selected title:(NSString *)title; +- (id)initWithItems:(NSArray *)stringArray selectedItems:(NSArray *)selectedItems title:(NSString *)title; + +- (id)initWithItems:(NSArray *)stringArray selected:(NSUInteger)selected; +- (id)initWithItems:(NSArray *)stringArray selected:(NSUInteger)selected title:(NSString *)title; + +- (void)addOption:(NSString *)option; +- (void)insertOption:(NSString *)option atIndex:(NSUInteger)index; + +- (void)createElements; + +@end diff --git a/quickdialog/QSelectSection.m b/quickdialog/QSelectSection.m new file mode 100644 index 00000000..018cd71c --- /dev/null +++ b/quickdialog/QSelectSection.m @@ -0,0 +1,109 @@ +// +// QSelectSection.m +// QuickDialog +// +// Created by HiveHicks on 23.03.12. +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#import "QSelectSection.h" + +@implementation QSelectSection + +@synthesize selectedIndexes = _selected; +@synthesize multipleAllowed = _multipleAllowed; +@synthesize onSelected = _onSelected; + + +- (QSelectSection *)initWithItems:(NSArray *)stringArray selectedIndexes:(NSArray *)selected +{ + return [self initWithItems:stringArray selectedIndexes:selected title:nil]; +} + +- (QSelectSection *)initWithItems:(NSArray *)stringArray selectedIndexes:(NSArray *)selected title:(NSString *)title +{ + if (self = [super initWithTitle:title]) + { + _items = [stringArray mutableCopy]; + _selected = selected ? [selected mutableCopy] : [NSMutableArray array]; + _multipleAllowed = (_selected.count > 1); + + [self createElements]; + } + + return self; +} + +- (QSelectSection *)initWithItems:(NSArray *)items selectedItems:(NSArray *)selectedItems title:(NSString *)title +{ + NSMutableArray *selectedIndexes = [NSMutableArray array]; + for (id item in selectedItems) { + NSUInteger index = [items indexOfObject:item]; + if (index != NSNotFound) { + [selectedIndexes addObject:[NSNumber numberWithUnsignedInteger:index]]; + } + } + + return [self initWithItems:items selectedIndexes:selectedIndexes title:title]; +} + +- (QSelectSection *)initWithItems:(NSArray *)stringArray selected:(NSUInteger)selected +{ + return [self initWithItems:stringArray selected:selected title:nil]; +} + +- (QSelectSection *)initWithItems:(NSArray *)stringArray selected:(NSUInteger)selected title:(NSString *)title +{ + return [self initWithItems:stringArray + selectedIndexes:[NSArray arrayWithObject:[NSNumber numberWithUnsignedInteger:selected]] + title:title]; +} + +- (NSArray *)items +{ + return _items; +} + +- (void)setItems:(NSArray *)items +{ + _items = [items mutableCopy]; + self.elements = nil; + [self createElements]; +} + +- (NSArray *)selectedItems +{ + NSMutableArray *selectedItems = [NSMutableArray array]; + for (NSNumber *index in _selected) { + [selectedItems addObject:[_items objectAtIndex:[index unsignedIntegerValue]]]; + } + return selectedItems; +} + +- (void)createElements +{ + for (NSUInteger i = 0; i < [_items count]; i++) { + [self addElement:[[QSelectItemElement alloc] initWithIndex:i selectSection:self]]; + } +} + +- (void)addOption:(NSString *)option +{ + [self insertOption:option atIndex:_items.count]; +} + +- (void)insertOption:(NSString *)option atIndex:(NSUInteger)index +{ + [_items insertObject:option atIndex:index]; + QSelectItemElement *element = [[QSelectItemElement alloc] initWithIndex:index selectSection:self]; + [self insertElement:element atIndex:index]; +} + +- (void)fetchValueIntoObject:(id)obj +{ + if (_key) { + [obj setValue:_selected forKey:_key]; + } +} + +@end diff --git a/quickdialog/QSortingSection.h b/quickdialog/QSortingSection.h index 3e1a4240..22c5e191 100644 --- a/quickdialog/QSortingSection.h +++ b/quickdialog/QSortingSection.h @@ -22,6 +22,11 @@ @property(nonatomic, assign) BOOL sortingEnabled; +@property(nonatomic, assign) BOOL canDeleteRows; + - (void)moveElementFromRow:(NSUInteger)from toRow:(NSUInteger)to; +- (BOOL)removeElementForRow:(NSInteger)integer; + +- (BOOL)canRemoveElementForRow:(NSInteger)integer; @end \ No newline at end of file diff --git a/quickdialog/QSortingSection.m b/quickdialog/QSortingSection.m index 0d0e7589..4bd406c7 100644 --- a/quickdialog/QSortingSection.m +++ b/quickdialog/QSortingSection.m @@ -16,16 +16,19 @@ #import "QSortingSection.h" #import "QElement.h" -@implementation QSortingSection +@implementation QSortingSection { + +} @synthesize sortingEnabled = _sortingEnabled; +@synthesize canDeleteRows = _canDeleteRows; + - (QSortingSection *)init { self = [super init]; self.sortingEnabled = YES; return self; - } - (BOOL)needsEditing { @@ -44,8 +47,16 @@ - (void)fetchValueIntoObject:(id)obj { } - (void)moveElementFromRow:(NSUInteger)from toRow:(NSUInteger)to { - [self.elements exchangeObjectAtIndex:from withObjectAtIndex:to]; + [self.elements moveObjectFromIndex:from toIndex:to]; } +- (BOOL)removeElementForRow:(NSInteger)index { + [self.elements removeObjectAtIndex:(NSUInteger) index]; + return YES; +} + +- (BOOL)canRemoveElementForRow:(NSInteger)integer { + return YES; +} @end \ No newline at end of file diff --git a/quickdialog/QTableViewCell.h b/quickdialog/QTableViewCell.h index 4ca022c9..961f4b7d 100644 --- a/quickdialog/QTableViewCell.h +++ b/quickdialog/QTableViewCell.h @@ -16,10 +16,15 @@ #import #import "QuickDialog.h" -@interface QTableViewCell : UITableViewCell { +typedef enum { + QLabelingPolicyTrimTitle, + QLabelingPolicyTrimValue +} QLabelingPolicy; - -} +@interface QTableViewCell : UITableViewCell - (QTableViewCell *)initWithReuseIdentifier:(NSString *)string; + +@property (nonatomic) QLabelingPolicy labelingPolicy; + @end \ No newline at end of file diff --git a/quickdialog/QTableViewCell.m b/quickdialog/QTableViewCell.m index a7be3306..20c67918 100644 --- a/quickdialog/QTableViewCell.m +++ b/quickdialog/QTableViewCell.m @@ -15,32 +15,39 @@ @implementation QTableViewCell +@synthesize labelingPolicy = _labelingPolicy; - (QTableViewCell *)initWithReuseIdentifier:(NSString *)string { self = [super initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:string]; - return self; } -- (void)layoutSubviews { +- (void)layoutSubviews +{ [super layoutSubviews]; - CGSize valueSize = CGSizeZero; - if (self.detailTextLabel.text!=nil) - valueSize = [self.detailTextLabel.text sizeWithFont:self.detailTextLabel.font]; + self.textLabel.backgroundColor = [UIColor clearColor]; + self.detailTextLabel.backgroundColor = [UIColor clearColor]; CGSize imageSize = CGSizeZero; if (self.imageView!=nil) imageSize = self.imageView.frame.size; - CGRect labelFrame = self.textLabel.frame; - self.textLabel.frame = CGRectMake(labelFrame.origin.x, labelFrame.origin.y, - self.contentView.bounds.size.width - valueSize.width - imageSize.width - 20, labelFrame.size.height); - - CGRect detailsFrame = self.detailTextLabel.frame; - self.detailTextLabel.frame = CGRectMake( - self.contentView.bounds.size.width - valueSize.width - 10, - detailsFrame.origin.y, valueSize.width, detailsFrame.size.height); + if (_labelingPolicy == QLabelingPolicyTrimTitle) + { + CGSize valueSize = CGSizeZero; + if (self.detailTextLabel.text!=nil) + valueSize = [self.detailTextLabel.text sizeWithFont:self.detailTextLabel.font]; + + CGRect labelFrame = self.textLabel.frame; + self.textLabel.frame = CGRectMake(labelFrame.origin.x, labelFrame.origin.y, + self.contentView.bounds.size.width - valueSize.width - imageSize.width - 20, labelFrame.size.height); + + CGRect detailsFrame = self.detailTextLabel.frame; + self.detailTextLabel.frame = CGRectMake( + self.contentView.bounds.size.width - valueSize.width - 10, + detailsFrame.origin.y, valueSize.width, detailsFrame.size.height); + } } @end \ No newline at end of file diff --git a/quickdialog/QTextElement.h b/quickdialog/QTextElement.h index 95be8c37..ed80e1c5 100644 --- a/quickdialog/QTextElement.h +++ b/quickdialog/QTextElement.h @@ -15,7 +15,7 @@ #import "QElement.h" -@interface QTextElement : QElement { +@interface QTextElement : QRootElement { @protected NSString *_text; diff --git a/quickdialog/QTextElement.m b/quickdialog/QTextElement.m index 82a32d41..dc7fee6c 100644 --- a/quickdialog/QTextElement.m +++ b/quickdialog/QTextElement.m @@ -12,6 +12,7 @@ // permissions and limitations under the License. // +#import #import "QTextElement.h" @implementation QTextElement @@ -35,38 +36,34 @@ - (QTextElement *)initWithText:(NSString *)text { } - (UITableViewCell *)getCellForTableView:(QuickDialogTableView *)tableView controller:(QuickDialogController *)controller { + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:[NSString stringWithFormat:@"QuickformText"]]; + if (cell == nil){ + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"QuickformText"]; + } + cell.selectionStyle = UITableViewCellSelectionStyleNone; + cell.detailTextLabel.lineBreakMode = UILineBreakModeWordWrap; + cell.detailTextLabel.numberOfLines = 0; - UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"QuickfromTextElement"]; - if (cell==nil){ - cell = [[QTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"QuickfromTextElement"]; - cell.selectionStyle = UITableViewCellSelectionStyleNone; + cell.textLabel.adjustsFontSizeToFitWidth = YES; + cell.textLabel.text = self.title; + cell.detailTextLabel.font = _font; + cell.detailTextLabel.textColor = _color; + cell.detailTextLabel.text = _text; - cell.textLabel.font = _font; - cell.textLabel.lineBreakMode = UILineBreakModeWordWrap; - cell.textLabel.numberOfLines = 0; - if([cell.textLabel respondsToSelector:@selector(textLabel:)]) { - cell.textLabel.textColor = _color; - } - cell.textLabel.text = _text; - } return cell; } -- (void)selected:(QuickDialogTableView *)tableView controller:(QuickDialogController *)controller indexPath:(NSIndexPath *)indexPath { - if (self.onSelected) { - self.onSelected(); - } - -} - (CGFloat)getRowHeightForTableView:(QuickDialogTableView *)tableView { if (_text==nil || _text == @""){ return [super getRowHeightForTableView:tableView]; } - CGSize constraint = CGSizeMake(280, 20000); + CGSize constraint = CGSizeMake(tableView.frame.size.width-(tableView.root.grouped ? 40.f : 20.f), 20000); CGSize size= [_text sizeWithFont:_font constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap]; CGFloat predictedHeight = size.height + 20.0f; + if (self.title!=nil) + predictedHeight+=30; return (_height >= predictedHeight) ? _height : predictedHeight; } diff --git a/quickdialog/QTextField.h b/quickdialog/QTextField.h new file mode 100644 index 00000000..d9163e2b --- /dev/null +++ b/quickdialog/QTextField.h @@ -0,0 +1,23 @@ +// +// Copyright 2011 ESCOZ Inc - http://escoz.com +// Created by hivehicks on 5/23/12. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software distributed under +// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +// ANY KIND, either express or implied. See the License for the specific language governing +// permissions and limitations under the License. +// + +#import + +@interface QTextField : UITextField + +@property (nonatomic, copy) NSString *prefix; +@property (nonatomic, copy) NSString *suffix; + +@end \ No newline at end of file diff --git a/quickdialog/QTextField.m b/quickdialog/QTextField.m new file mode 100644 index 00000000..8671244f --- /dev/null +++ b/quickdialog/QTextField.m @@ -0,0 +1,32 @@ +// +// Copyright 2011 ESCOZ Inc - http://escoz.com +// Created by hivehicks on 5/23/12. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software distributed under +// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +// ANY KIND, either express or implied. See the License for the specific language governing +// permissions and limitations under the License. +// + +@implementation QTextField + +@synthesize prefix = _prefix; +@synthesize suffix = _suffix; + +- (void)drawTextInRect:(CGRect)rect +{ + if (_prefix || _suffix) { + NSString *textWithSuffix = [NSString stringWithFormat:@"%@%@%@", _prefix ? _prefix : @"", self.text, _suffix ? _suffix : @""]; + CGContextSetFillColorWithColor(UIGraphicsGetCurrentContext(), self.textColor.CGColor); + [textWithSuffix drawInRect:rect withFont:self.font lineBreakMode:UILineBreakModeTailTruncation alignment:self.textAlignment]; + } else { + [super drawTextInRect:rect]; + } +} + +@end \ No newline at end of file diff --git a/quickdialog/QWebElement.h b/quickdialog/QWebElement.h index a540aa4d..24d2be75 100644 --- a/quickdialog/QWebElement.h +++ b/quickdialog/QWebElement.h @@ -15,7 +15,7 @@ #import #import "QRootElement.h" -@interface QWebElement : QRootElement { +@interface QWebElement : QLabelElement { @protected NSString *_url; diff --git a/quickdialog/QWebElement.m b/quickdialog/QWebElement.m index 03b6a5f7..8277adb6 100644 --- a/quickdialog/QWebElement.m +++ b/quickdialog/QWebElement.m @@ -28,6 +28,7 @@ - (QWebElement *)initWithTitle:(NSString *)title url:(NSString *)url { - (void)selected:(QuickDialogTableView *)tableView controller:(QuickDialogController *)controller indexPath:(NSIndexPath *)path { + [self handleElementSelected:controller]; if ([_url hasPrefix:@"http"]) { QWebViewController *webController = [[QWebViewController alloc] initWithUrl:_url]; [controller displayViewController:webController]; diff --git a/quickdialog/QWebViewController.m b/quickdialog/QWebViewController.m index 954ad4e2..7788c4ef 100644 --- a/quickdialog/QWebViewController.m +++ b/quickdialog/QWebViewController.m @@ -33,7 +33,7 @@ - (QWebViewController *)initWithUrl:(NSString *)url { if (self!=nil){ _webView = [[UIWebView alloc] init]; _webView.delegate = self; - _webView.scalesPageToFit = YES; + _webView.scalesPageToFit = YES; _url = url; self.view = _webView; @@ -44,6 +44,8 @@ - (QWebViewController *)initWithUrl:(NSString *)url { _btBack.enabled = NO; _btForward.enabled = NO; + + self.hidesBottomBarWhenPushed = YES; } return self; } @@ -81,7 +83,6 @@ - (void)viewWillAppear:(BOOL)animated { [_webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:_url]]]; _previousToolbarState = self.navigationController.toolbarHidden; self.navigationController.toolbarHidden = NO; - UIBarButtonItem *spacer1 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil]; spacer1.width = 30; @@ -123,8 +124,8 @@ - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error { if (error.code==-999) return; self.navigationItem.rightBarButtonItem = nil; - self.title = @"Error"; - [_webView loadHTMLString:[NSString stringWithFormat:@"An error occurred:
%@
", [error localizedDescription]] baseURL:nil]; + self.navigationItem.title = @"Error"; + [_webView loadHTMLString:[NSString stringWithFormat:@"

Could not open page %@.


%@

",_url, [error localizedDescription]] baseURL:nil]; } diff --git a/quickdialog/QuickDialog.h b/quickdialog/QuickDialog.h index e29b76a5..7742be9f 100644 --- a/quickdialog/QuickDialog.h +++ b/quickdialog/QuickDialog.h @@ -14,12 +14,15 @@ #import "QuickDialogController.h" +#import "QuickDialogWebController.h" #import "QuickDialogController+Loading.h" +#import "QuickDialogController+Helpers.h" +#import "NSMutableArray+MoveObject.h" #import "QuickDialogTableView.h" #import "QuickDialogTableDelegate.h" #import "QTableViewCell.h" -#import "QRootElement+Builder.h" +#import "QRootElement+JsonBuilder.h" #import "QLoadingElement.h" #import "QRootElement.h" #import "QLabelElement.h" @@ -30,9 +33,12 @@ #import "QEntryTableViewCell.h" #import "QDateTimeInlineElement.h" #import "QFloatElement.h" +#import "QPickerElement.h" #import "QMapElement.h" #import "QRadioElement.h" #import "QRadioItemElement.h" +#import "QPickerElement.h" +#import "QSelectItemElement.h" #import "QTextElement.h" #import "QWebElement.h" #import "QDecimalElement.h" @@ -40,6 +46,9 @@ #import "QDateTimeElement.h" #import "QWebViewController.h" #import "QBadgeLabel.h" +#import "QSegmentedElement.h" +#import "QMultilineTextViewController.h" +#import "QMultilineElement.h" #import "QuickDialogStyleProvider.h" #import "QuickDialogEntryElementDelegate.h" @@ -47,4 +56,13 @@ #import "QRootBuilder.h" #import "QValidator.h" -#import "QEntryValidator.h" \ No newline at end of file +#import "QEntryValidator.h" +#import "QuickDialogController+Loading.h" + +#import "QAutoEntryElement.h" +#import "QAutoEntryTableViewCell.h" +#import "QDateEntryTableViewCell.h" + +#import "QRootBuilder.h" + +#import "QTextField.h" diff --git a/quickdialog/QuickDialogController+Helpers.h b/quickdialog/QuickDialogController+Helpers.h new file mode 100644 index 00000000..3dc82641 --- /dev/null +++ b/quickdialog/QuickDialogController+Helpers.h @@ -0,0 +1,8 @@ +#import + +NSString *QTranslate(NSString *value); + + +@interface QuickDialogController (Helpers) + +@end \ No newline at end of file diff --git a/quickdialog/QuickDialogController+Helpers.m b/quickdialog/QuickDialogController+Helpers.m new file mode 100644 index 00000000..d087e5bc --- /dev/null +++ b/quickdialog/QuickDialogController+Helpers.m @@ -0,0 +1,13 @@ +#import "QuickDialogController+Helpers.h" + + +NSString *QTranslate(NSString *value) { + NSString * translated = NSLocalizedString(value, nil); + //if ([translated isEqualToString:value]) + // NSLog(@"\"%@\" = \"%@\";", value, value); + return translated; +} + + +@implementation QuickDialogController (Helpers) +@end \ No newline at end of file diff --git a/quickdialog/QuickDialogController+Loading.m b/quickdialog/QuickDialogController+Loading.m index 9b04dea5..4eb325b9 100644 --- a/quickdialog/QuickDialogController+Loading.m +++ b/quickdialog/QuickDialogController+Loading.m @@ -30,20 +30,19 @@ - (UIView *)createLoadingView { [loading addSubview:activity]; - [self.quickDialogTableView.superview addSubview:loading]; - [self.quickDialogTableView.superview bringSubviewToFront:loading]; + [self.quickDialogTableView addSubview:loading]; + [self.quickDialogTableView bringSubviewToFront:loading]; return loading; } - (void)loading:(BOOL)visible { [UIApplication sharedApplication].networkActivityIndicatorVisible = visible; - UIView *loadingView = [self.quickDialogTableView.superview viewWithTag:1123002]; + UIView *loadingView = [self.quickDialogTableView viewWithTag:1123002]; if (loadingView==nil){ loadingView = [self createLoadingView]; } - loadingView.frame = CGRectMake(0, 0, self.quickDialogTableView.bounds.size.width, self.quickDialogTableView.bounds.size.height); - + loadingView.frame = CGRectMake(self.quickDialogTableView.contentOffset.x, self.quickDialogTableView.contentOffset.y, self.quickDialogTableView.bounds.size.width, self.quickDialogTableView.bounds.size.height); self.quickDialogTableView.userInteractionEnabled = !visible; if (visible) diff --git a/quickdialog/QuickDialogController.h b/quickdialog/QuickDialogController.h index c679b873..c5c1a23b 100644 --- a/quickdialog/QuickDialogController.h +++ b/quickdialog/QuickDialogController.h @@ -41,6 +41,7 @@ - (void)displayViewControllerForRoot:(QRootElement *)element; - (QuickDialogController *)controllerForRoot:(QRootElement *)root; + + (QuickDialogController *)controllerForRoot:(QRootElement *)root; + (UINavigationController *)controllerWithNavigationForRoot:(QRootElement *)root; diff --git a/quickdialog/QuickDialogController.m b/quickdialog/QuickDialogController.m index 1bfd1a76..b3d0565d 100644 --- a/quickdialog/QuickDialogController.m +++ b/quickdialog/QuickDialogController.m @@ -62,6 +62,8 @@ + (UINavigationController*)controllerWithNavigationForRoot:(QRootElement *)root - (void)loadView { [super loadView]; self.quickDialogTableView = [[QuickDialogTableView alloc] initWithController:self]; + self.quickDialogTableView.backgroundView = nil; + self.quickDialogTableView.backgroundColor = [UIColor colorWithRed:223.0f/255.0f green:223.0f/255.0f blue:223.0f/255.0f alpha:1.0]; self.view = self.quickDialogTableView; } @@ -79,6 +81,11 @@ - (QuickDialogController *)initWithRoot:(QRootElement *)rootElement { return self; } +-(void)setEditing:(BOOL)editing animated:(BOOL)animated { + [super setEditing:editing animated:animated]; + [self.quickDialogTableView setEditing:editing animated:animated]; +} + - (void)setRoot:(QRootElement *)root { _root = root; self.quickDialogTableView.root = root; @@ -102,7 +109,7 @@ - (void)viewWillDisappear:(BOOL)animated { } } -- (void)popToPreviousRootElement { +- (void)popToPreviousRootElementOnMainThread { if (self.navigationController!=nil){ [self.navigationController popViewControllerAnimated:YES]; } else { @@ -110,6 +117,10 @@ - (void)popToPreviousRootElement { } } +- (void)popToPreviousRootElement { + [self performSelectorOnMainThread:@selector(popToPreviousRootElementOnMainThread) withObject:nil waitUntilDone:YES]; +} + - (void)displayViewController:(UIViewController *)newController { if (self.navigationController != nil ){ [self.navigationController pushViewController:newController animated:YES]; @@ -151,7 +162,8 @@ - (void) resizeForKeyboard:(NSNotification*)aNotification { [UIView animateWithDuration:animationDuration delay:0 options:animationCurve animations:^{ CGRect keyboardFrame = [self.view convertRect:keyboardEndFrame toView:nil]; - self.quickDialogTableView.contentInset = UIEdgeInsetsMake(0.0, 0.0, up ? keyboardFrame.size.height : 0, 0.0); + const UIEdgeInsets oldInset = self.quickDialogTableView.contentInset; + self.quickDialogTableView.contentInset = UIEdgeInsetsMake(oldInset.top, oldInset.left, up ? keyboardFrame.size.height : 0, oldInset.right); } completion:NULL]; } @@ -163,16 +175,35 @@ - (void)setResizeWhenKeyboardPresented:(BOOL)observesKeyboard { if (_resizeWhenKeyboardPresented) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resizeForKeyboard:) name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resizeForKeyboard:) name:UIKeyboardWillHideNotification object:nil]; + +#ifdef __IPHONE_5_0 + float version = [[[UIDevice currentDevice] systemVersion] floatValue]; + if (version >= 5.0) { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resizeForKeyboard:) name:UIKeyboardWillChangeFrameNotification object:nil]; + } +#endif } else { [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil]; +#ifdef __IPHONE_5_0 + float version = [[[UIDevice currentDevice] systemVersion] floatValue]; + if (version >= 5.0) { + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillChangeFrameNotification object:nil]; + } +#endif + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil]; } } } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil]; +#ifdef __IPHONE_5_0 + float version = [[[UIDevice currentDevice] systemVersion] floatValue]; + if (version >= 5.0) { + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillChangeFrameNotification object:nil]; + } +#endif + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil]; } diff --git a/quickdialog/QuickDialogDataSource.m b/quickdialog/QuickDialogDataSource.m index cf9f91f5..21c80d80 100644 --- a/quickdialog/QuickDialogDataSource.m +++ b/quickdialog/QuickDialogDataSource.m @@ -31,11 +31,8 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { QSection *section = [_tableView.root getSectionForIndex:indexPath.section]; - QElement * element = [section.elements objectAtIndex:(NSUInteger) indexPath.row]; + QElement *element = [section.elements objectAtIndex:(NSUInteger) indexPath.row]; UITableViewCell *cell = [element getCellForTableView:(QuickDialogTableView *) tableView controller:_tableView.controller]; - if (_tableView.styleProvider!=nil){ - [_tableView.styleProvider cell:cell willAppearForElement:element atIndexPath:indexPath]; - } return cell; } @@ -55,13 +52,25 @@ - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *) return [[_tableView.root getSectionForIndex:indexPath.section] isKindOfClass:[QSortingSection class]]; } + +- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { + QSortingSection *section = ((QSortingSection *) [_tableView.root.sections objectAtIndex:(NSUInteger) indexPath.section]); + if ([section removeElementForRow:indexPath.row]){ + [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; + } +} + - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath { QSortingSection *section = ((QSortingSection *) [_tableView.root.sections objectAtIndex:(NSUInteger) sourceIndexPath.section]); [section moveElementFromRow:(NSUInteger) sourceIndexPath.row toRow:(NSUInteger) destinationIndexPath.row]; } - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { - return [[_tableView.root getSectionForIndex:indexPath.section] isKindOfClass:[QSortingSection class]]; + QSection *section = [_tableView.root.sections objectAtIndex:(NSUInteger) indexPath.section]; + if ([section isKindOfClass:[QSortingSection class]]){ + return ([(QSortingSection *) section canRemoveElementForRow:indexPath.row]); + } + return tableView.editing; } @end \ No newline at end of file diff --git a/quickdialog/QuickDialogEntryElementDelegate.h b/quickdialog/QuickDialogEntryElementDelegate.h index 189d037e..7eb063a5 100644 --- a/quickdialog/QuickDialogEntryElementDelegate.h +++ b/quickdialog/QuickDialogEntryElementDelegate.h @@ -10,7 +10,7 @@ - (void)QEntryEditingChangedForElement:(QEntryElement *)element andCell:(QEntryTableViewCell *)cell; - (void)QEntryDidBeginEditingElement:(QEntryElement *)element andCell:(QEntryTableViewCell *)cell; - (void)QEntryDidEndEditingElement:(QEntryElement *)element andCell:(QEntryTableViewCell *)cell; -- (void)QEntryShouldReturnForElement:(QEntryElement *)element andCell:(QEntryTableViewCell *)cell; +- (BOOL)QEntryShouldReturnForElement:(QEntryElement *)element andCell:(QEntryTableViewCell *)cell; - (void)QEntryMustReturnForElement:(QEntryElement *)element andCell:(QEntryTableViewCell *)cell; @end \ No newline at end of file diff --git a/quickdialog/QuickDialogTableDelegate.m b/quickdialog/QuickDialogTableDelegate.m index aba4da7b..6596a2f3 100644 --- a/quickdialog/QuickDialogTableDelegate.m +++ b/quickdialog/QuickDialogTableDelegate.m @@ -12,15 +12,7 @@ // permissions and limitations under the License. // - -#import "QuickDialogTableDelegate.h" -#import "QuickDialogController.h" -#import "QElement.h" -#import "QSection.h" -#import "QSortingSection.h" -#import "QRootElement.h" -#import "QuickDialogTableView.h" - +#import "UIImageView+QuickDialogTableView.h" @implementation QuickDialogTableDelegate @@ -29,6 +21,13 @@ - (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NS return indexPath; } +- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath { + QSection *section = [_tableView.root getSectionForIndex:indexPath.section]; + QElement * element = [section.elements objectAtIndex:(NSUInteger) indexPath.row]; + + [element selectedAccessory:_tableView controller:_tableView.controller indexPath:indexPath]; +} + - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { QSection *section = [_tableView.root getSectionForIndex:indexPath.section]; QElement * element = [section.elements objectAtIndex:(NSUInteger) indexPath.row]; @@ -44,12 +43,14 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath return self; } + - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath { - return UITableViewCellEditingStyleNone; + QSection *section = [_tableView.root getSectionForIndex:indexPath.section]; + return section.canDeleteRows ? UITableViewCellEditingStyleDelete : UITableViewCellEditingStyleNone; } - (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath { - return NO; + return YES; } - (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath { @@ -74,7 +75,27 @@ - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSIntege if (section.headerView!=nil) return section.headerView.frame.size.height; - return section.title == NULL? 0 : _tableView.root.grouped? 44 : 22; + if (section.title==nil) + return 0; + + if (!_tableView.root.grouped) + return 22.f; + + CGFloat stringTitleHeight = 0; + + if (section.title != nil) { + CGFloat maxWidth = [UIScreen mainScreen].bounds.size.width - 20; + CGFloat maxHeight = 9999; + CGSize maximumLabelSize = CGSizeMake(maxWidth,maxHeight); + CGSize expectedLabelSize = [section.title sizeWithFont:[UIFont systemFontOfSize:[UIFont labelFontSize]] + constrainedToSize:maximumLabelSize + lineBreakMode:UILineBreakModeWordWrap]; + + stringTitleHeight = expectedLabelSize.height+23.f; + } + + + return section.title != NULL? stringTitleHeight : 0; } - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)index { @@ -90,19 +111,45 @@ - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSIntege CGFloat stringFooterHeight = 28.0; if (section.footer != nil) { - CGFloat maxWidth = [UIScreen mainScreen].bounds.size.width - 50; + CGFloat maxWidth = [UIScreen mainScreen].bounds.size.width - 20; CGFloat maxHeight = 9999; CGSize maximumLabelSize = CGSizeMake(maxWidth,maxHeight); CGSize expectedLabelSize = [section.footer sizeWithFont:[UIFont systemFontOfSize:[UIFont labelFontSize]] constrainedToSize:maximumLabelSize lineBreakMode:UILineBreakModeWordWrap]; - stringFooterHeight = expectedLabelSize.height; + stringFooterHeight = expectedLabelSize.height+5; } return section.footer != NULL? stringFooterHeight : 0; } +- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { + QSection *section = [_tableView.root getSectionForIndex:indexPath.section]; + QElement *element = [section.elements objectAtIndex:(NSUInteger) indexPath.row]; + + QuickDialogTableViewCellPosition cellPosition; + if (section.elements.count >= 2) { + if (indexPath.row == 0) { + cellPosition = kQuickDialogTableViewCellPositionTop; + } else if (indexPath.row == section.elements.count - 1) { + cellPosition = kQuickDialogTableViewCellPositionBottom; + } else { + cellPosition = kQuickDialogTableViewCellPositionCenter; + } + } else { + cellPosition = kQuickDialogTableViewCellPositionSingle; + } + + // set the background view + cell.backgroundView = [UIImageView backgroundViewAtQuickDialogTableViewPosition:cellPosition forState:kQuickDialogTableViewCellStateNormal]; + cell.selectedBackgroundView = [UIImageView backgroundViewAtQuickDialogTableViewPosition:cellPosition forState:kQuickDialogTableViewCellStateSelected]; + + if (_tableView.styleProvider != nil) { + [_tableView.styleProvider cell:cell willAppearForElement:element atIndexPath:indexPath]; + } +} + - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)index { QSection *section = [_tableView.root getSectionForIndex:index]; diff --git a/quickdialog/QuickDialogTableView.h b/quickdialog/QuickDialogTableView.h index 9af9b5c9..048c6cb3 100644 --- a/quickdialog/QuickDialogTableView.h +++ b/quickdialog/QuickDialogTableView.h @@ -29,14 +29,13 @@ QRootElement *_root; id quickformDataSource; id quickformDelegate; - UITableViewCell *_selectedCell; } @property(nonatomic, strong) QRootElement *root; @property(nonatomic, readonly) QuickDialogController *controller; -@property(nonatomic, retain) NSObject *styleProvider; +@property(nonatomic, assign) NSObject *styleProvider; @property(nonatomic) BOOL deselectRowWhenViewAppears; diff --git a/quickdialog/QuickDialogTableView.m b/quickdialog/QuickDialogTableView.m index dc0d9e8a..ef5acb01 100644 --- a/quickdialog/QuickDialogTableView.m +++ b/quickdialog/QuickDialogTableView.m @@ -88,7 +88,10 @@ - (void)reloadCellForElements:(QElement *)firstElement, ... { NSMutableArray *indexes = [[NSMutableArray alloc] init]; QElement * element = firstElement; while (element != nil) { - [indexes addObject:[self indexForElement:element]]; + NSIndexPath *index = [self indexForElement:element]; + if (index != nil) { + [indexes addObject:index]; + } element = va_arg(args, QElement *); } [self reloadRowsAtIndexPaths:indexes withRowAnimation:UITableViewRowAnimationNone]; diff --git a/quickdialog/QuickDialogWebController.h b/quickdialog/QuickDialogWebController.h new file mode 100644 index 00000000..0307b9fd --- /dev/null +++ b/quickdialog/QuickDialogWebController.h @@ -0,0 +1,11 @@ +#import + + +@interface QuickDialogWebController : QuickDialogController + +@property(nonatomic, strong) NSString * url; + +- (void)reload; + + +@end \ No newline at end of file diff --git a/quickdialog/QuickDialogWebController.m b/quickdialog/QuickDialogWebController.m new file mode 100644 index 00000000..d451e3b5 --- /dev/null +++ b/quickdialog/QuickDialogWebController.m @@ -0,0 +1,60 @@ +#import "QuickDialogWebController.h" + + +@implementation QuickDialogWebController { + +} + +@synthesize url; + +- (NSURLRequest *)createRequestForUrl { + return [[NSURLRequest alloc] initWithURL:[[NSURL alloc] initWithString:self.url]]; +} + +- (void)presentError:(NSError *)error { + [self.root bindToObject:[NSDictionary dictionary]]; + [self.quickDialogTableView reloadData]; + [[[UIAlertView alloc] initWithTitle:@"Error" message:error.localizedDescription delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show]; + [self loading:NO]; +} + +- (void)presentResult:(NSData *)data { + NSError *jsonError; + NSDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError]; + + if (jsonError==nil){ + [self.root bindToObject:responseDict]; + [self.quickDialogTableView reloadData]; + } + + [self loading:NO]; +} + +- (void)reload { + NSURLRequest *request = [self createRequestForUrl]; + [NSURLConnection sendAsynchronousRequest:request + queue:[NSOperationQueue currentQueue] + completionHandler:^(NSURLResponse *response, NSData *data, NSError *err) { + if (err){ + [self presentError:err]; + return; + } + [self presentResult:data]; + + }]; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + if (self.url==nil && [self.root.object isKindOfClass:[NSString class]]) + self.url = (NSString *) self.root.object; + + if (self.url!=nil){ + [self loading:YES]; + [self reload]; + } + +} + + +@end \ No newline at end of file diff --git a/quickdialog/UIImageView+QuickDialogTableView.h b/quickdialog/UIImageView+QuickDialogTableView.h new file mode 100644 index 00000000..516d4930 --- /dev/null +++ b/quickdialog/UIImageView+QuickDialogTableView.h @@ -0,0 +1,27 @@ +// +// UIImageView+TableView.h +// QuickDialog +// +// Created by Tao Ma on 12/17/12. +// +// + +#import + +typedef enum { + kQuickDialogTableViewCellPositionTop, + kQuickDialogTableViewCellPositionCenter, + kQuickDialogTableViewCellPositionBottom, + kQuickDialogTableViewCellPositionSingle +} QuickDialogTableViewCellPosition; + +typedef enum { + kQuickDialogTableViewCellStateNormal, + kQuickDialogTableViewCellStateSelected +} QuickDialogTableViewCellState; + +@interface UIImageView (QuickDialogTableView) + ++ (UIImageView *)backgroundViewAtQuickDialogTableViewPosition:(QuickDialogTableViewCellPosition)cellPosition forState:(QuickDialogTableViewCellState)cellState; + +@end diff --git a/quickdialog/UIImageView+QuickDialogTableView.m b/quickdialog/UIImageView+QuickDialogTableView.m new file mode 100644 index 00000000..ab8e286e --- /dev/null +++ b/quickdialog/UIImageView+QuickDialogTableView.m @@ -0,0 +1,52 @@ +// +// UIImageView+TableView.m +// QuickDialog +// +// Created by Tao Ma on 12/17/12. +// +// + +#import "UIImageView+QuickDialogTableView.h" + +@implementation UIImageView (QuickDialogTableView) + ++ (UIImageView *)backgroundViewAtQuickDialogTableViewPosition:(QuickDialogTableViewCellPosition)cellPosition forState:(QuickDialogTableViewCellState)cellState { + UIImageView *imageView = nil; + if (cellPosition == kQuickDialogTableViewCellPositionTop) { + if (cellState == kQuickDialogTableViewCellStateNormal) { + UIImage *image = [[UIImage imageNamed:@"cell-top-default.png"] stretchableImageWithLeftCapWidth:5.0 topCapHeight:5.0]; + imageView = [[UIImageView alloc] initWithImage:image]; + } else if (cellState == kQuickDialogTableViewCellStateSelected) { + UIImage *image = [[UIImage imageNamed:@"cell-top-selected.png"] stretchableImageWithLeftCapWidth:5.0 topCapHeight:5.0]; + imageView = [[UIImageView alloc] initWithImage:image]; + } + } else if (cellPosition == kQuickDialogTableViewCellPositionCenter) { + if (cellState == kQuickDialogTableViewCellStateNormal) { + UIImage *image = [[UIImage imageNamed:@"cell-center-default.png"] stretchableImageWithLeftCapWidth:5.0 topCapHeight:5.0]; + imageView = [[UIImageView alloc] initWithImage:image]; + } else if (cellState == kQuickDialogTableViewCellStateSelected) { + UIImage *image = [[UIImage imageNamed:@"cell-center-selected.png"] stretchableImageWithLeftCapWidth:5.0 topCapHeight:5.0]; + imageView = [[UIImageView alloc] initWithImage:image]; + } + } else if (cellPosition == kQuickDialogTableViewCellPositionBottom) { + if (cellState == kQuickDialogTableViewCellStateNormal) { + UIImage *image = [[UIImage imageNamed:@"cell-bottom-default.png"] stretchableImageWithLeftCapWidth:5.0 topCapHeight:5.0]; + imageView = [[UIImageView alloc] initWithImage:image]; + } else if (cellState == kQuickDialogTableViewCellStateSelected) { + UIImage *image = [[UIImage imageNamed:@"cell-bottom-selected.png"] stretchableImageWithLeftCapWidth:5.0 topCapHeight:5.0]; + imageView = [[UIImageView alloc] initWithImage:image]; + } + } else if (cellPosition == kQuickDialogTableViewCellPositionSingle) { + if (cellState == kQuickDialogTableViewCellStateNormal) { + UIImage *image = [[UIImage imageNamed:@"cell-single-default.png"] stretchableImageWithLeftCapWidth:5.0 topCapHeight:5.0]; + imageView = [[UIImageView alloc] initWithImage:image]; + } else if (cellState == kQuickDialogTableViewCellStateSelected) { + UIImage *image = [[UIImage imageNamed:@"cell-single-selected.png"] stretchableImageWithLeftCapWidth:5.0 topCapHeight:5.0]; + imageView = [[UIImageView alloc] initWithImage:image]; + } + } + + return imageView; +} + +@end diff --git a/sample/AboutController.h b/sample/AboutController.h index e2da1ea7..ea3e38d1 100644 --- a/sample/AboutController.h +++ b/sample/AboutController.h @@ -14,8 +14,9 @@ #import "LoginController.h" +// Subclassing from LoginController in order to inherit the quickDialogTableview style settings. @interface AboutController : LoginController { } -@end \ No newline at end of file +@end diff --git a/sample/ExampleAppDelegate.m b/sample/ExampleAppDelegate.m index 0d017e5b..28205142 100644 --- a/sample/ExampleAppDelegate.m +++ b/sample/ExampleAppDelegate.m @@ -9,7 +9,7 @@ // Unless required by applicable law or agreed to in writing, software distributed under // the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF // ANY KIND, either express or implied. See the License for the specific language governing -// permissions and limitations under the License. +// permissions and limitatio ns under the License. // #import "SampleDataBuilder.h" diff --git a/sample/ExampleViewController.m b/sample/ExampleViewController.m index 433cf259..325e80ac 100644 --- a/sample/ExampleViewController.m +++ b/sample/ExampleViewController.m @@ -32,6 +32,10 @@ - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interface } } +-(void)handleWebElementControllerAction:(QWebElement *)element { + NSLog(@"Web element selected for url %@", element.url); +} + -(void)handleChangeEntryExample:(QButtonElement *) button { QEntryElement *entry = (QEntryElement *) [self.root elementWithKey:@"entryElement"]; entry.textValue = @"Hello"; diff --git a/sample/JsonDataSampleController.m b/sample/JsonDataSampleController.m index d4fb80f8..25b107a1 100644 --- a/sample/JsonDataSampleController.m +++ b/sample/JsonDataSampleController.m @@ -31,10 +31,23 @@ - (void)handleBindToObject:(QElement *)button { [dataDict setValue:@"Bound from object" forKey:@"sectionTitle"]; [dataDict setValue:[NSNumber numberWithBool:NO] forKey:@"bool"]; [dataDict setValue:[NSNumber numberWithFloat:0.9] forKey:@"float"]; + [dataDict setValue:[NSNumber numberWithFloat:1] forKey:@"radio"]; [self.root bindToObject:dataDict]; - [self.quickDialogTableView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0,1)] withRowAnimation:UITableViewRowAnimationFade]; + [self.quickDialogTableView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0,2)] withRowAnimation:UITableViewRowAnimationFade]; } +-(void)readValuesFromForm:(QElement *)button { + NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; + [self.root fetchValueUsingBindingsIntoObject:dict]; + + NSString *msg = @"Values:"; + for (NSString *aKey in dict){ + msg = [msg stringByAppendingFormat:@"\n- %@: %@", aKey, [dict valueForKey:aKey]]; + } + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Hello" + message:msg delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil]; + [alert show]; +} -(void)handleSetValuesDirectly:(QElement *)button { NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init]; diff --git a/sample/Localizable.strings b/sample/Localizable.strings index 03ce8b08..4b804c2b 100644 --- a/sample/Localizable.strings +++ b/sample/Localizable.strings @@ -5,9 +5,14 @@ "Previous" = "Previous"; "Next" = "Next"; "Done" = "Done"; -"Yesterday" = "Yesterday"; -"Tomorrow" = "Tomorrow"; -"1 day ago" = "1 day ago"; -"%d days ago" = "%d days ago"; -"1 week ago" = "1 week ago"; -"%d weeks ago" = "%d weeks ago"; \ No newline at end of file + + + +"Metric %li" = "Metric %li"; +"REVENUE" = "REVENUE"; +"TRANSACTIONS" = "TRANSACTIONS"; +"CONVERSION RATE" = "CONVERSION RATE"; +"GOALS VALUE" = "GOALS VALUE"; +"GOALS TOTAL" = "GOALS TOTAL"; +"NEW VISITS" = "NEW VISITS"; +"TAP AND HOLD\nto change the metric" = "TAP AND HOLD\nto change the metric"; \ No newline at end of file diff --git a/sample/LoginController.h b/sample/LoginController.h index bbdb858c..194a4328 100644 --- a/sample/LoginController.h +++ b/sample/LoginController.h @@ -17,5 +17,4 @@ } + (QRootElement *)createDetailsForm; -+ (QRootElement *)createLoginForm; @end \ No newline at end of file diff --git a/sample/LoginController.m b/sample/LoginController.m index 59c0a9aa..7ec39dc1 100644 --- a/sample/LoginController.m +++ b/sample/LoginController.m @@ -26,6 +26,7 @@ @implementation LoginController - (void)setQuickDialogTableView:(QuickDialogTableView *)aQuickDialogTableView { [super setQuickDialogTableView:aQuickDialogTableView]; + self.quickDialogTableView.backgroundView = nil; self.quickDialogTableView.backgroundColor = [UIColor colorWithHue:0.1174 saturation:0.7131 brightness:0.8618 alpha:1.0000]; self.quickDialogTableView.bounces = NO; self.quickDialogTableView.styleProvider = self; @@ -46,15 +47,16 @@ - (void)viewWillDisappear:(BOOL)animated { - (void)loginCompleted:(LoginInfo *)info { [self loading:NO]; - UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Welcome" message:[NSString stringWithFormat: @"Hi %@, you're loving QuickForms!", info.login] delegate:self cancelButtonTitle:@"YES!" otherButtonTitles:nil]; + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Welcome" message:[NSString stringWithFormat: @"Hi %@, I hope you're loving QuickDialog! Here's your pass: %@", info.login, info.password] delegate:self cancelButtonTitle:@"YES!" otherButtonTitles:nil]; [alert show]; } - (void)onLogin:(QButtonElement *)buttonElement { + + [[[UIApplication sharedApplication] keyWindow] endEditing:YES]; [self loading:YES]; LoginInfo *info = [[LoginInfo alloc] init]; - [self.root fetchValueIntoObject:info]; - + [self.root fetchValueUsingBindingsIntoObject:info]; [self performSelector:@selector(loginCompleted:) withObject:info afterDelay:2]; } @@ -84,45 +86,6 @@ + (QRootElement *)createDetailsForm { return details; } -+ (QRootElement *)createLoginForm { - QRootElement *root = [[QRootElement alloc] init]; - root.controllerName = @"LoginController"; - root.grouped = YES; - root.title = @"Login"; - - QSection *main = [[QSection alloc] init]; - main.headerImage = @"logo"; - - QEntryElement *login = [[QEntryElement alloc] init]; - login.title = @"Username"; - login.key = @"login"; - login.hiddenToolbar = YES; - login.placeholder = @"johndoe@me.com"; - [main addElement:login]; - - QEntryElement *password = [[QEntryElement alloc] init]; - password.title = @"Password"; - password.key = @"password"; - password.secureTextEntry = YES; - password.hiddenToolbar = YES; - password.placeholder = @"your password"; - [main addElement:password]; - - [root addSection:main]; - - QSection *btSection = [[QSection alloc] init]; - QButtonElement *btLogin = [[QButtonElement alloc] init]; - btLogin.title = @"Login"; - btLogin.controllerAction = @"onLogin:"; - [btSection addElement:btLogin]; - - [root addSection:btSection]; - - btSection.footerImage = @"footer"; - - return root; -} - - (BOOL)QEntryShouldChangeCharactersInRangeForElement:(QEntryElement *)element andCell:(QEntryTableViewCell *)cell { NSLog(@"Should change characters"); return YES; diff --git a/sample/PeriodPickerValueParser.h b/sample/PeriodPickerValueParser.h new file mode 100644 index 00000000..59e96a49 --- /dev/null +++ b/sample/PeriodPickerValueParser.h @@ -0,0 +1,15 @@ +// +// AMPeriodPickerValueParser.h +// AutoMobile +// +// Created by HiveHicks on 11.04.12. +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#import + +@interface PeriodPickerValueParser : NSObject + +@property (nonatomic, readonly) NSArray *stringPeriods; + +@end diff --git a/sample/PeriodPickerValueParser.m b/sample/PeriodPickerValueParser.m new file mode 100644 index 00000000..96a5df04 --- /dev/null +++ b/sample/PeriodPickerValueParser.m @@ -0,0 +1,56 @@ +// +// AMPeriodPickerValueParser.m +// AutoMobile +// +// Created by HiveHicks on 11.04.12. +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#import "PeriodPickerValueParser.h" + +@implementation PeriodPickerValueParser { + NSDictionary *valuesMap; +} + +- (id)init +{ + if (self = [super init]) + { + valuesMap = + [NSDictionary dictionaryWithObjectsAndKeys: + @"daily", [NSNumber numberWithUnsignedInteger:NSDayCalendarUnit], + @"weekly", [NSNumber numberWithUnsignedInteger:NSWeekCalendarUnit], + @"monthly", [NSNumber numberWithUnsignedInteger:NSMonthCalendarUnit], + @"yearly", [NSNumber numberWithUnsignedInteger:NSYearCalendarUnit], nil]; + } + + return self; +} + +- (NSArray *)stringPeriods +{ + return [valuesMap allValues]; +} + +- (id)objectFromComponentsValues:(NSArray *)componentsValues +{ + NSString *stringPeriod = [componentsValues objectAtIndex:0]; + for (NSNumber *calendarUnitWrapper in valuesMap) { + if ([[valuesMap objectForKey:calendarUnitWrapper] isEqualToString:stringPeriod]) { + return calendarUnitWrapper; + } + } + return nil; +} + +- (NSArray *)componentsValuesFromObject:(id)object +{ + return [NSArray arrayWithObject:[valuesMap objectForKey:object]]; +} + +- (NSString *)presentationOfObject:(id)object +{ + return [valuesMap objectForKey:object]; +} + +@end diff --git a/sample/Resources/jsondatasample.json b/sample/Resources/jsondatasample.json index af14c04c..fe0065cf 100644 --- a/sample/Resources/jsondatasample.json +++ b/sample/Resources/jsondatasample.json @@ -10,14 +10,18 @@ }, { "elements":[ { "type":"QBooleanElement", "title":"Boolean", "boolValue":0, "bind":"boolValue:bool"}, - { "type":"QFloatElement", "title":"Progress", "floatValue":0, "bind":"floatValue:float"} + { "type":"QFloatElement", "title":"Progress", "floatValue":0, "bind":"floatValue:float"}, + { "type":"QRadioElement", "title":"Radio", "selected":0, "bind":"selectedValue:radio", "items":["item 1", "item 2", "item 3"]} ] }, { "elements":[ { "type":"QButtonElement", "key":"bt1", "title":"Set values directly", "controllerAction":"handleSetValuesDirectly:"}, { "type":"QButtonElement", "key":"bt2", "title":"Bind to Object", "controllerAction":"handleBindToObject:"} , { "type":"QButtonElement", "key":"bt2", "title":"Load JSON with Object", "controllerAction":"handleLoadJsonWithDict:"}, - { "type":"QButtonElement", "key":"bt3", "title":"Load JSON", "controllerAction":"handleReloadJson:"} + { "type":"QButtonElement", "key":"bt3", "title":"Load JSON", "controllerAction":"handleReloadJson:"}, + { "type":"QButtonElement", "key":"bt4", "title":"Read Values from Form", "controllerAction":"readValuesFromForm:"} + + ] } ] diff --git a/sample/Resources/jsonremote.json b/sample/Resources/jsonremote.json new file mode 100644 index 00000000..df37084e --- /dev/null +++ b/sample/Resources/jsonremote.json @@ -0,0 +1,27 @@ +{ + "grouped": false, + "title": "Remote Files", + "controllerName": "QuickDialogWebController", + "object":"https://github.com/api/v2/json/commits/list/escoz/quickdialog/master", + "sections": [ + { + "elements":[ + { "type":"QTextElement", "text":"This controller automatically downloads data from the web and binds it to the form. Data is downloaded from GitHub."} + ] + }, + { "title":"Commits for QuickDialog", "bind":"iterate:commits", "elementTemplate": + { "type":"QTextElement", "bind":"text:message, title:committed_date", "controllerName":"QuickDialogController", "grouped":true, "sections":[ + {"title":"Dates", "elements":[ + { "type":"QLabelElement", "title":"Committed date", "bind":"value:committed_date"}, + { "type":"QLabelElement", "title":"Authored date", "bind":"value:authored_date"} + ]}, + {"title":"Committer", "bind":"iterateproperties:committer", "elementTemplate": + { "type":"QLabelElement", "bind":"title:key, value:value"} + }, + {"title":"Author", "bind":"iterateproperties:author", "elementTemplate": + { "type":"QLabelElement", "bind":"title:key, value:value"} + } + ]} + } + ] +} \ No newline at end of file diff --git a/sample/Resources/loginform.json b/sample/Resources/loginform.json index 05858bfc..652220f7 100644 --- a/sample/Resources/loginform.json +++ b/sample/Resources/loginform.json @@ -4,8 +4,8 @@ "controllerName": "LoginController", "sections": [ { "title":"Awesome Login Form", "headerImage":"logo", "footer":"Please type your credentials.", "elements": [ - { "type":"QEntryElement", "key":"login", "title":"Login","placeholder":"Login or email"}, - { "type":"QEntryElement","key":"password", "title":"Password", "placeholder":"Password", "secureTextEntry":true } + { "type":"QEntryElement", "title":"Login","placeholder":"Login or email", "bind":"textValue:login"}, + { "type":"QEntryElement", "title":"Password", "placeholder":"Password", "secureTextEntry":true, "bind":"textValue:password" } ] }, { "elements":[ diff --git a/sample/Resources/sample.json b/sample/Resources/sample.json index d82cef9a..d639deaf 100644 --- a/sample/Resources/sample.json +++ b/sample/Resources/sample.json @@ -2,17 +2,7 @@ "grouped": true, "title": "Sample Controls", "sections": [ - { "title":"Entry Elements", "elements":[ - { "type":"QEntryElement", "title":"secureTextEntry", "placeholder":"Text", "secureTextEntry":true }, - { "type":"QEntryElement", "title":"enablesReturnKey", "placeholder":"Text", "enablesReturnKeyAutomatically":true }, - { "type":"QEntryElement", "title":"autocapitalizationType", "placeholder":"Words", "autocapitalizationType":"Words" }, - { "type":"QEntryElement", "title":"autocorrectionType", "placeholder":"No", "autocorrectionType":"No" }, - { "type":"QEntryElement", "title":"keyboardType", "placeholder":"PhonePad", "keyboardType":"PhonePad" }, - { "type":"QEntryElement", "title":"keyboardAppearance", "placeholder":"Alert", "keyboardAppearance":"Alert" }, - { "type":"QEntryElement", "title":"returnKeyType", "placeholder":"EmergencyCall", "returnKeyType":"EmergencyCall" } - ] - } , { "title":"Controls", "elements":[ {"type":"QLabelElement", "title":"Label"}, {"type":"QBadgeElement", "title":"Badge", "badge":"123"}, @@ -20,7 +10,9 @@ {"type":"QBooleanElement", "title":"Boolean", "boolValue":1}, {"type":"QButtonElement", "title":"Button"}, {"type":"QDateTimeInlineElement", "title":"DateTime Inline"}, - {"type":"QFloatElement", "title":"Float", "floatValue":0.54}, + {"type":"QPickerElement", "title":"Picker1", "items":[["Blue", "Yellow", "Green"]]}, + {"type":"QPickerElement", "title":"Picker2", "items":[[1, 2, 3], ["Blue", "Yellow", "Green"]]}, + {"type":"QPickerElement", "title":"Picker3", "items":[[1, 2, 3], ["Blue", "Yellow", "Green"], ["Metal","Chrome","Wood"]]}, {"type":"QMapElement", "title":"Map", "lat":-27.59, "lng":-48.55}, {"type":"QRadioElement", "title":"Radio", "items":["Option 1", "Option 2", "Final option"], "selected":2}, {"type":"QTextElement", "text":"Text Element"}, @@ -28,7 +20,20 @@ {"type":"QTextElement", "text":"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."}, {"type":"QLoadingElement"} ] - } + }, + { "title":"Entry Elements", "elements":[ + { "type":"QEntryElement", "title":"secureTextEntry", "placeholder":"Text", "secureTextEntry":true }, + { "type":"QEntryElement", "title":"enablesReturnKey", "placeholder":"Text", "enablesReturnKeyAutomatically":true }, + { "type":"QEntryElement", "title":"autocapitalizationType", "placeholder":"Words", "autocapitalizationType":"Words" }, + { "type":"QEntryElement", "title":"autocorrectionType", "placeholder":"No", "autocorrectionType":"No" }, + { "type":"QEntryElement", "title":"keyboardType", "placeholder":"PhonePad", "keyboardType":"PhonePad" }, + { "type":"QEntryElement", "title":"keyboardAppearance", "placeholder":"Alert", "keyboardAppearance":"Alert" }, + { "type":"QEntryElement", "title":"returnKeyType", "placeholder":"EmergencyCall", "returnKeyType":"EmergencyCall" } + ] + } , + { "elements":[ + {"type":"QSegmentedElement", "items":["Senna", "Fittipaldi", "Schumacher"], "selected":1} + ]} ] } \ No newline at end of file diff --git a/sample/SampleDataBuilder.m b/sample/SampleDataBuilder.m index 64fe8d37..9757647f 100644 --- a/sample/SampleDataBuilder.m +++ b/sample/SampleDataBuilder.m @@ -12,13 +12,10 @@ // permissions and limitations under the License. // -#import #import -#import "LoginController.h" #import "SampleDataBuilder.h" -#import "QRootElement.h" -#import "QSection.h" #import "QDynamicDataSection.h" +#import "PeriodPickerValueParser.h" @implementation SampleDataBuilder @@ -37,11 +34,11 @@ + (QRootElement *)createWithInitDefault { [subsection addElement:[[QDateTimeInlineElement alloc] init]]; [subsection addElement:[[QFloatElement alloc] init]]; [subsection addElement:[[QMapElement alloc] init]]; + [subsection addElement:[[QPickerElement alloc] init]]; [subsection addElement:[[QRadioElement alloc] init]]; [subsection addElement:[[QRadioItemElement alloc] init]]; [subsection addElement:[[QTextElement alloc] init]]; [subsection addElement:[[QWebElement alloc] init]]; - return subForm; } @@ -55,6 +52,7 @@ + (QRootElement *)createWithInitAndKey { [subForm addSection:subsection]; [subsection addElement:[[QLabelElement alloc] initWithKey:@"Key1"]]; + [subsection addElement:[[QMultilineElement alloc] initWithKey:@"Key3"]]; [subsection addElement:[[QBadgeElement alloc] initWithKey:@"Key1"]]; [subsection addElement:[[QBooleanElement alloc] initWithKey:@"Key1"]]; [subsection addElement:[[QButtonElement alloc] initWithKey:@"Key1"]]; @@ -72,7 +70,7 @@ + (QRootElement *)createWithInitAndKey { + (QElement *)reallyLongList { QRootElement *subForm = [[QRootElement alloc] init]; subForm.title = @"Really long list"; - QSection *subsection = [[QSection alloc] initWithTitle:@"Long List"]; + QSection *subsection = [[QSection alloc] initWithTitle:@"Long title for the long list of elements"]; for (int i = 0; i<1000; i++){ QBooleanElement *bool1 = [[QBooleanElement alloc] initWithTitle:[NSString stringWithFormat:@"Option %d", i] BoolValue:(i % 3 == 0)]; bool1.onImage = [UIImage imageNamed:@"imgOn"]; @@ -148,22 +146,30 @@ + (QElement *)createSampleControls { QLabelElement *element1 = [[QLabelElement alloc] initWithTitle:@"Label" Value:@"element"]; - QRadioElement *radioElement = [[QRadioElement alloc] initWithItems:[[NSArray alloc] initWithObjects:@"Option 1", @"Option 2", @"Option 3", nil] selected:0 title:@"Radio"]; radioElement.key = @"radio1"; + + QBooleanElement *boolElement = [[QBooleanElement alloc] initWithTitle:@"Boolean Element" BoolValue:YES]; boolElement.controllerAction = @"exampleAction:"; boolElement.key = @"bool1"; QEntryElement *entryElement = [[QEntryElement alloc] initWithTitle:@"Entry Element" Value:nil Placeholder:@"type here"]; entryElement.key = @"entry1"; - + + NSArray *values = [NSArray arrayWithObjects:@"Ferrari", @"Ms.",@"Mrs.",@"Miss",@"Mr.",@"Prof.",@"A/Prof.",nil]; + QAutoEntryElement *autoElement = [[QAutoEntryElement alloc] initWithTitle:@"AutoComplete" value:nil placeholder:@"type letter M"]; + autoElement.autoCompleteValues = values; + autoElement.autoCompleteColor = [UIColor orangeColor]; + autoElement.key = @"entry2"; + controls.footer = @"More controls will be added."; [controls addElement:element1]; [controls addElement:radioElement]; [controls addElement:entryElement]; + [controls addElement:autoElement]; [controls addElement:boolElement]; QDateTimeInlineElement *dateElement = [[QDateTimeInlineElement alloc] initWithTitle:@"DateTime" date:[NSDate date]]; @@ -176,7 +182,7 @@ + (QElement *)createSampleControls { QDecimalElement *decimal = [[QDecimalElement alloc] initWithTitle:@"Decimal Element" value:0.5]; decimal.key = @"decimal1"; - decimal.fractionDigits = 3; + decimal.fractionDigits = 2; [controls addElement:decimal]; QLabelElement *element2 = [[QLabelElement alloc] initWithTitle:@"Label Different Height" Value:@"70"]; @@ -189,13 +195,14 @@ + (QElement *)createSampleControls { QButtonElement *button = [[QButtonElement alloc] initWithTitle:@"Show form values"]; button.onSelected = ^{ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Hello" - message:[NSString stringWithFormat:@"1: %d\n2: %@\n3: %d\n4:%@\n5:%f\n6:%f", + message:[NSString stringWithFormat:@"1: %d\n2: %@\n3: %d\n4:%@\n5:%f\n6:%f\n7:%@", radioElement.selected , entryElement.textValue, boolElement.boolValue, dateElement.dateValue , slider.floatValue, - decimal.floatValue] + decimal.floatValue, + autoElement.textValue] delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil]; @@ -223,7 +230,15 @@ + (QElement *)createSampleControls { [btnSection2 addElement:button2]; btnSection2.footer = @"Here's a really long footer text that could be used to make your users happy!"; + QSection *segmented = [[QSection alloc] initWithTitle:@"Here's a long title for this segmented control"]; + segmented.footer = @"And heres a long footer text for this segmented control"; + + QSegmentedElement *segmentedElement = [[QSegmentedElement alloc] initWithItems:[[NSArray alloc] initWithObjects:@"Option 1", @"Option 2", @"Option 3", nil] selected:0 title:@"Radio"]; + radioElement.key = @"segmented1"; + [segmented addElement:segmentedElement]; + [root addSection:controls]; + [root addSection:segmented]; [root addSection:btnSection]; [root addSection:btnSection2]; return root; @@ -237,15 +252,83 @@ + (QElement *)createRadioRoot { QSection *section1 = [[QSection alloc] initWithTitle:@"Radio element with push"]; [section1 addElement:[[QRadioElement alloc] initWithItems:[NSArray arrayWithObjects:@"Football", @"Soccer", @"Formula 1", nil] selected:0]]; [section1 addElement:[[QRadioElement alloc] initWithItems:[NSArray arrayWithObjects:@"Football", @"Soccer", @"Formula 1", nil] selected:0 title:@"Sport"]]; + [section1 addElement:[[QRadioElement alloc] initWithDict:[NSDictionary dictionaryWithObjectsAndKeys:@"FerrariObj", @"Ferrari", @"McLarenObj", @"McLaren", @"MercedesObj", @"Mercedes", nil] selected:0 title:@"With Dict"]]; + QRadioElement *elementWithAction = [[QRadioElement alloc] initWithItems:[NSArray arrayWithObjects:@"Ferrari", @"McLaren", @"Lotus", nil] selected:0 title:@"WithAction"]; elementWithAction.controllerAction = @"exampleAction:"; [section1 addElement:elementWithAction]; [root addSection:section1]; - QSection *section2 = [[QRadioSection alloc] initWithItems:[NSArray arrayWithObjects:@"Football", @"Soccer", @"Formula 1", nil] selected:0 title:@"Sport"]; + QRadioSection *section2 = [[QRadioSection alloc] initWithItems:[NSArray arrayWithObjects:@"Football", @"Soccer", @"Formula 1", nil] selected:0 title:@"Sport"]; + section2.onSelected = ^{ NSLog(@"selected index: %d", section2.selected); }; [root addSection:section2]; + return root; +} ++ (QElement *)createPickerRoot +{ + QRootElement *root = [[QRootElement alloc] init]; + root.title = @"Picker"; + root.grouped = YES; + + QSection *simplePickerSection = [[QSection alloc] initWithTitle:@"Picker element"]; + + NSMutableArray *component1 = [NSMutableArray array]; + for (int i = 1; i <= 12; i++) { + [component1 addObject:[NSString stringWithFormat:@"%d", i]]; + } + + NSArray *component2 = [NSArray arrayWithObjects:@"A", @"B", nil]; + + QPickerElement *simplePickerEl = + [[QPickerElement alloc] initWithTitle:@"Key" + items:[NSArray arrayWithObjects:component1, component2, nil] + value:@"3 B"]; + simplePickerEl.onValueChanged = ^{ NSLog(@"Selected indexes: %@", [simplePickerEl.selectedIndexes componentsJoinedByString:@","]); }; + + [simplePickerSection addElement:simplePickerEl]; + [root addSection:simplePickerSection]; + + QSection *customParserSection = [[QSection alloc] initWithTitle:@"Custom value parser"]; + + PeriodPickerValueParser *periodParser = [[PeriodPickerValueParser alloc] init]; + + QPickerElement *periodPickerEl = + [[QPickerElement alloc] initWithTitle:@"Period" + items:[NSArray arrayWithObject:periodParser.stringPeriods] + value:[NSNumber numberWithUnsignedInteger:NSMonthCalendarUnit]]; + + periodPickerEl.valueParser = periodParser; + periodPickerEl.onValueChanged = ^{ NSLog(@"New value: %@", periodPickerEl.value); }; + + [customParserSection addElement:periodPickerEl]; + [root addSection:customParserSection]; + + return root; +} + ++ (QElement *)createSelectRoot +{ + QRootElement *root = [[QRootElement alloc] init]; + root.title = @"Select"; + root.grouped = YES; + + QSelectSection *simpleSelectSection = + [[QSelectSection alloc] initWithItems:[NSArray arrayWithObjects:@"Football", @"Soccer", @"Formula 1", nil] + selectedIndexes:nil title:@"Simple select"]; + + QSelectSection *multipleSelectSection = + [[QSelectSection alloc] initWithItems:[NSArray arrayWithObjects:@"Football", @"Soccer", @"Formula 1", nil] + selectedIndexes:[NSArray arrayWithObjects: + [NSNumber numberWithUnsignedInteger:0], + [NSNumber numberWithUnsignedInteger:1], nil] + title:@"Multiple select"]; + multipleSelectSection.multipleAllowed = YES; + + [root addSection:simpleSelectSection]; + [root addSection:multipleSelectSection]; + return root; } @@ -254,6 +337,7 @@ + (QRootElement *)createWebAndMapRoot { root.title = @"Web and map"; QWebElement *element1 = [[QWebElement alloc] initWithTitle:@"ESCOZ Inc" url:@"http://escoz.com"]; + element1.controllerAction = @"handleWebElementControllerAction:"; QWebElement *element2 = [[QWebElement alloc] initWithTitle:@"Quicklytics" url:@"http://escoz.com/quicklytics"]; QMapElement *element4 = [[QMapElement alloc] initWithTitle:@"Florianopolis, Brazil" coordinate:CLLocationCoordinate2DMake(-27.59, -48.55)]; @@ -340,9 +424,20 @@ + (QRootElement *)createLabelsRoot { [sec addElement:[[QBadgeElement alloc] initWithTitle:@"Test 3" Value:@"200"]]; [sec addElement:[[QBadgeElement alloc] initWithTitle:@"Test 4" Value:@"1000"]]; [sec addElement:[[QBadgeElement alloc] initWithTitle:@"Test 5" Value:@"TEST"]]; + + QSection *s3 = [[QSection alloc] initWithTitle:@"Labeling policies"]; + + QLabelElement *trimTitleEl = [[QLabelElement alloc] initWithTitle:@"QLabelingPolicyTrimTitle" Value:@"really really really long value"]; + trimTitleEl.labelingPolicy = QLabelingPolicyTrimTitle; // this is default + [s3 addElement:trimTitleEl]; + + QLabelElement *trimValueEl = [[QLabelElement alloc] initWithTitle:@"QLabelingPolicyTrimValue" Value:@"really really really long value"]; + trimValueEl.labelingPolicy = QLabelingPolicyTrimValue; + [s3 addElement:trimValueEl]; [root addSection:s1]; [root addSection:s2]; + [root addSection:s3]; [root addSection:secImg]; @@ -363,13 +458,33 @@ + (QRootElement *)createEntryRoot { [firstSection addElement:[[QEntryElement alloc] initWithTitle:@"With Very Long Title" Value:@"" Placeholder:@"text"]]; [root addSection:firstSection]; + + QSection *prefixSuffixSection = [[QSection alloc] initWithTitle:@"Prefix/suffix"]; + prefixSuffixSection.footer = @"Prefix/suffix is only displayed, they're not stored in textValue"; + + QEntryElement *prefixElement = [[QEntryElement alloc] initWithTitle:nil Value:nil Placeholder:@"with prefix"]; + prefixElement.keyboardType = UIKeyboardTypeNumberPad; + prefixElement.prefix = @"$"; + + QEntryElement *suffixElement = [[QEntryElement alloc] initWithTitle:nil Value:nil Placeholder:@"with suffix"]; + suffixElement.keyboardType = UIKeyboardTypeNumberPad; + suffixElement.suffix = @" km"; + + QEntryElement *prefixSuffixElement = [[QEntryElement alloc] initWithTitle:nil Value:nil Placeholder:@"with prefix and suffix"]; + prefixSuffixElement.prefix = @"* "; + prefixSuffixElement.suffix = @" *"; + + [prefixSuffixSection addElement:prefixElement]; + [prefixSuffixSection addElement:suffixElement]; + [prefixSuffixSection addElement:prefixSuffixElement]; + [root addSection:prefixSuffixSection]; QSection *traitsSection = [[QSection alloc] initWithTitle:@"UITextInputTraits"]; QEntryElement *secureElement = [[QEntryElement alloc] initWithTitle:@"Secure" Value:@"" Placeholder:@"YES"]; secureElement.secureTextEntry = YES; [traitsSection addElement:secureElement]; - + QEntryElement *keyboardTypeElement = [[QEntryElement alloc] initWithTitle:@"KB Type" Value:@"" Placeholder:@"NumberPad"]; keyboardTypeElement.keyboardType = UIKeyboardTypeNumberPad; [traitsSection addElement:keyboardTypeElement]; @@ -393,8 +508,17 @@ + (QRootElement *)createEntryRoot { QEntryElement *enableReturnElement = [[QEntryElement alloc] initWithTitle:@"Auto Return" Value:@"" Placeholder:@"YES"]; enableReturnElement.enablesReturnKeyAutomatically = YES; [traitsSection addElement:enableReturnElement]; - + + QSection *multilineSection = [[QSection alloc] initWithTitle:@"Entry Elements"]; + + + QMultilineElement *multiline = [QMultilineElement new]; + multiline.title = @"Multiline entry"; + [multilineSection addElement:multiline]; + + [root addSection:traitsSection]; + [root addSection:multilineSection]; return root; } @@ -487,7 +611,13 @@ + (QElement *)createDynamicSectionRoot { QRootElement *const root = [[QRootElement alloc] init ]; root.title = @"Dynamic Data Sections"; root.grouped = YES; - + + + QDynamicDataSection *defaultSection = [QDynamicDataSection new]; + defaultSection.title = @"Default: loading"; + defaultSection.emptyMessage = @"This is empty"; + [root addSection: defaultSection]; + QDynamicDataSection *emptySection = [QDynamicDataSection new]; emptySection.title = @"Empty: elements = empty list"; emptySection.bind = @"iterate:empty"; @@ -503,10 +633,17 @@ + (QElement *)createDynamicSectionRoot { QDynamicDataSection *section = [QDynamicDataSection new]; section.title = @"Normal: with elements"; - [section addElement:[[QLabelElement alloc] initWithTitle:@"Something" Value:@"ok"]]; + section.bind = @"iterate:something"; + section.elementTemplate = [NSDictionary dictionaryWithObjectsAndKeys: + @"QLabelElement", @"type", + @"Something here", @"title", + nil]; [root addSection: section]; - [root bindToObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSArray array], @"empty", nil, @"nil", nil]]; + [root bindToObject:[NSDictionary dictionaryWithObjectsAndKeys: + [NSArray array], @"empty", + [NSArray arrayWithObjects:@"first", @"second", nil], @"something", + nil]]; return root; } @@ -517,7 +654,7 @@ + (QRootElement *)create { root.title = @"QuickForms!"; QSection *sectionSamples = [[QSection alloc] init]; sectionSamples.headerView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"quickdialog"]]; - [sectionSamples addElement:[LoginController createLoginForm]]; + [sectionSamples addElement:[[QRootElement alloc] initWithJSONFile:@"loginform"]]; [sectionSamples addElement:[self createSampleControls]]; [sectionSamples addElement:[self createSampleFormRoot]]; [sectionSamples addElement:[self reallyLongList]]; @@ -529,6 +666,8 @@ + (QRootElement *)create { [sectionElements addElement:[self createEntryRoot]]; [sectionElements addElement:[self createSlidersRoot]]; [sectionElements addElement:[self createRadioRoot]]; + [sectionElements addElement:[self createPickerRoot]]; + [sectionElements addElement:[self createSelectRoot]]; [sectionElements addElement:[self createWebAndMapRoot]]; [sectionElements addElement:[self createTextRoot]]; [sectionElements addElement:[self createDateTimeRoot]]; @@ -546,12 +685,15 @@ + (QRootElement *)create { [sectionJson addElement:[[QRootElement alloc] initWithJSONFile:@"sample"]]; [sectionJson addElement:[[QRootElement alloc] initWithJSONFile:@"jsondatasample"]]; [sectionJson addElement:[[QRootElement alloc] initWithJSONFile:@"jsonadvancedsample"]]; + [sectionJson addElement:[[QRootElement alloc] initWithJSONFile:@"jsonremote"]]; + + NSString *jsonSample = @"{\"title\": \"In memory struct\",\n" + " \"controllerName\": \"LoginController\", \"sections\":[]}"; + id const parsedJson = [NSJSONSerialization JSONObjectWithData:[jsonSample dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableLeaves error:nil]; + [sectionJson addElement:[[QRootElement alloc] initWithJSON:parsedJson andData:nil]]; [root addSection:sectionJson]; } - - - return root; } @end \ No newline at end of file