diff --git a/source/ios/AdaptiveCards/ADCIOSVisualizer/ADCIOSVisualizer.xcodeproj/project.pbxproj b/source/ios/AdaptiveCards/ADCIOSVisualizer/ADCIOSVisualizer.xcodeproj/project.pbxproj index 78a841a071..97aec89c43 100644 --- a/source/ios/AdaptiveCards/ADCIOSVisualizer/ADCIOSVisualizer.xcodeproj/project.pbxproj +++ b/source/ios/AdaptiveCards/ADCIOSVisualizer/ADCIOSVisualizer.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + 6B268FE320CEF19400D99C1B /* Action.Scrolling.json in Resources */ = {isa = PBXBuildFile; fileRef = 6B268FE220CEF19400D99C1B /* Action.Scrolling.json */; }; + 6B268FE520CEF89100D99C1B /* Action.OpenUrl.json in Resources */ = {isa = PBXBuildFile; fileRef = 6B268FE420CEF89100D99C1B /* Action.OpenUrl.json */; }; 6B7B1A9B20C21CA900260731 /* SportingEvent.json in Resources */ = {isa = PBXBuildFile; fileRef = 6B7B1A9920C21CA800260731 /* SportingEvent.json */; }; 6BF339D620A665E600DA5973 /* CustomTextBlockRenderer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6BF339D420A665E600DA5973 /* CustomTextBlockRenderer.mm */; }; 6BF339E320A66A3F00DA5973 /* AdaptiveCards.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6BF339E220A66A3F00DA5973 /* AdaptiveCards.framework */; }; @@ -21,7 +23,6 @@ F423C0881EE1FB6100905679 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F423C0861EE1FB6100905679 /* LaunchScreen.storyboard */; }; F423C0931EE1FB6100905679 /* ADCIOSVisualizerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F423C0921EE1FB6100905679 /* ADCIOSVisualizerTests.m */; }; F423C09E1EE1FB6100905679 /* ADCIOSVisualizerUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = F423C09D1EE1FB6100905679 /* ADCIOSVisualizerUITests.m */; }; - F4933CC21F79852C00F6EBFD /* Action.OpenUrl.json in Resources */ = {isa = PBXBuildFile; fileRef = F4933C951F79852C00F6EBFD /* Action.OpenUrl.json */; }; F4933CC31F79852C00F6EBFD /* Action.ShowCard.json in Resources */ = {isa = PBXBuildFile; fileRef = F4933C961F79852C00F6EBFD /* Action.ShowCard.json */; }; F4933CC41F79852C00F6EBFD /* Action.ShowCard.Style.json in Resources */ = {isa = PBXBuildFile; fileRef = F4933C971F79852C00F6EBFD /* Action.ShowCard.Style.json */; }; F4933CC51F79852C00F6EBFD /* Action.Submit.json in Resources */ = {isa = PBXBuildFile; fileRef = F4933C981F79852C00F6EBFD /* Action.Submit.json */; }; @@ -112,6 +113,8 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 6B268FE220CEF19400D99C1B /* Action.Scrolling.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = Action.Scrolling.json; path = resources/Action.Scrolling.json; sourceTree = ""; }; + 6B268FE420CEF89100D99C1B /* Action.OpenUrl.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = Action.OpenUrl.json; path = ../../../../samples/v1.0/Elements/Action.OpenUrl.json; sourceTree = ""; }; 6B7B1A9920C21CA800260731 /* SportingEvent.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = SportingEvent.json; path = ../../../../samples/v1.0/Scenarios/SportingEvent.json; sourceTree = ""; }; 6BF339D420A665E600DA5973 /* CustomTextBlockRenderer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CustomTextBlockRenderer.mm; sourceTree = ""; }; 6BF339D520A665E600DA5973 /* CustomTextBlockRenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomTextBlockRenderer.h; sourceTree = ""; }; @@ -134,7 +137,6 @@ F423C0991EE1FB6100905679 /* ADCIOSVisualizerUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ADCIOSVisualizerUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; F423C09D1EE1FB6100905679 /* ADCIOSVisualizerUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ADCIOSVisualizerUITests.m; sourceTree = ""; }; F423C09F1EE1FB6100905679 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - F4933C951F79852C00F6EBFD /* Action.OpenUrl.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = Action.OpenUrl.json; path = ../../../../samples/v1.0/Elements/Action.OpenUrl.json; sourceTree = ""; }; F4933C961F79852C00F6EBFD /* Action.ShowCard.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = Action.ShowCard.json; path = ../../../../samples/v1.0/Elements/Action.ShowCard.json; sourceTree = ""; }; F4933C971F79852C00F6EBFD /* Action.ShowCard.Style.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = Action.ShowCard.Style.json; path = ../../../../samples/v1.0/Elements/Action.ShowCard.Style.json; sourceTree = ""; }; F4933C981F79852C00F6EBFD /* Action.Submit.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = Action.Submit.json; path = ../../../../samples/v1.0/Elements/Action.Submit.json; sourceTree = ""; }; @@ -313,11 +315,11 @@ children = ( 6B7B1A9920C21CA800260731 /* SportingEvent.json */, F4F44BA6204CF97100A2F24C /* CustomParsingTestUsingProgressBar.json */, + F4933CFA1F79853B00F6EBFD /* WeatherCompact.json */, F4F44B842048CDB300A2F24C /* AdditionalProperty.json */, F4F44B8220478E1100A2F24C /* DateTimeTestTranslation.json */, F4071C821FD63D5300AF4FEA /* Solitaire.json */, F4D402151F7DB0BF00D0356B /* sample.json */, - F4933CEF1F79853B00F6EBFD /* ActivityUpdate.json */, F4933CF01F79853B00F6EBFD /* CalendarReminder.json */, F4933CF11F79853B00F6EBFD /* FlightItinerary.json */, F4933CF21F79853B00F6EBFD /* FlightUpdate.json */, @@ -327,9 +329,8 @@ F4933CF61F79853B00F6EBFD /* Inputs.json */, F4933CF71F79853B00F6EBFD /* Restaurant.json */, F4933CF91F79853B00F6EBFD /* StockUpdate.json */, - F4933CFA1F79853B00F6EBFD /* WeatherCompact.json */, F4933CFB1F79853B00F6EBFD /* WeatherLarge.json */, - F4933C951F79852C00F6EBFD /* Action.OpenUrl.json */, + F4933CEF1F79853B00F6EBFD /* ActivityUpdate.json */, F4933C961F79852C00F6EBFD /* Action.ShowCard.json */, F4933C971F79852C00F6EBFD /* Action.ShowCard.Style.json */, F4933C981F79852C00F6EBFD /* Action.Submit.json */, @@ -482,11 +483,11 @@ F4933CE41F79852C00F6EBFD /* TextBlock.Color.json in Resources */, F4933CD41F79852C00F6EBFD /* Image.HorizontalAlignment.json in Resources */, F4933CC51F79852C00F6EBFD /* Action.Submit.json in Resources */, + 6B268FE520CEF89100D99C1B /* Action.OpenUrl.json in Resources */, F4933CED1F79852C00F6EBFD /* TextBlock.Weight.json in Resources */, F4933D061F79853B00F6EBFD /* StockUpdate.json in Resources */, F4933D081F79853B00F6EBFD /* WeatherLarge.json in Resources */, F4933CCD1F79852C00F6EBFD /* ColumnSet.Spacing.json in Resources */, - F4933CC21F79852C00F6EBFD /* Action.OpenUrl.json in Resources */, F4933CFE1F79853B00F6EBFD /* FlightItinerary.json in Resources */, 6B7B1A9B20C21CA900260731 /* SportingEvent.json in Resources */, F4933CC81F79852C00F6EBFD /* Column.Style.json in Resources */, @@ -503,6 +504,7 @@ F4933D011F79853B00F6EBFD /* ImageGallery.json in Resources */, F4933D001F79853B00F6EBFD /* FoodOrder.json in Resources */, F4933CE21F79852C00F6EBFD /* Input.Toggle.json in Resources */, + 6B268FE320CEF19400D99C1B /* Action.Scrolling.json in Resources */, F4933CFC1F79853B00F6EBFD /* ActivityUpdate.json in Resources */, F4933CD51F79852C00F6EBFD /* Image.SelectAction.json in Resources */, F4071C831FD63D5400AF4FEA /* Solitaire.json in Resources */, diff --git a/source/ios/AdaptiveCards/ADCIOSVisualizer/resources/Action.Scrolling.json b/source/ios/AdaptiveCards/ADCIOSVisualizer/resources/Action.Scrolling.json new file mode 100644 index 0000000000..da7b2ee2be --- /dev/null +++ b/source/ios/AdaptiveCards/ADCIOSVisualizer/resources/Action.Scrolling.json @@ -0,0 +1,64 @@ +{ + "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", + "type": "AdaptiveCard", + "version": "1.0", + "body": [ + { + "type": "TextBlock", + "text": "This cards shows that action set will have scroll bar when it has more buttons than it can show", + "wrap": true + } + ], + "actions": [ + { + "type": "Action.OpenUrl", + "title": "button 1", + "url": "http://adaptivecards.io" + }, + { + "type": "Action.OpenUrl", + "title": "button 2", + "url": "http://adaptivecards.io" + }, + { + "type": "Action.OpenUrl", + "title": "button 3", + "url": "http://adaptivecards.io" + }, + { + "type": "Action.OpenUrl", + "title": "button 4", + "url": "http://adaptivecards.io" + }, + { + "type": "Action.OpenUrl", + "title": "button 5", + "url": "http://adaptivecards.io" + }, + { + "type": "Action.OpenUrl", + "title": "button 6", + "url": "http://adaptivecards.io" + }, + { + "type": "Action.OpenUrl", + "title": "button 7", + "url": "http://adaptivecards.io" + }, + { + "type": "Action.OpenUrl", + "title": "button 8", + "url": "http://adaptivecards.io" + }, + { + "type": "Action.OpenUrl", + "title": "button 9", + "url": "http://adaptivecards.io" + }, + { + "type": "Action.OpenUrl", + "title": "button 10", + "url": "http://adaptivecards.io" + } + ] +} diff --git a/source/ios/AdaptiveCards/ADCIOSVisualizer/resources/sample.json b/source/ios/AdaptiveCards/ADCIOSVisualizer/resources/sample.json index 02c6d366b0..9ff707347b 100644 --- a/source/ios/AdaptiveCards/ADCIOSVisualizer/resources/sample.json +++ b/source/ios/AdaptiveCards/ADCIOSVisualizer/resources/sample.json @@ -94,7 +94,7 @@ "style": "Emphasis" }, "preExpandSingleShowCardAction": false, - "actionsOrientation": "Vertical", + "actionsOrientation": "Horizontal", "actionAlignment": "Stretch" }, "adaptiveCard": { diff --git a/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards.xcodeproj/project.pbxproj b/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards.xcodeproj/project.pbxproj index 876dac60fa..7af86455ef 100644 --- a/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards.xcodeproj/project.pbxproj +++ b/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards.xcodeproj/project.pbxproj @@ -25,6 +25,8 @@ 6B1147D81F32F922008846EC /* ACRShowCardTarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 6B1147D61F32F922008846EC /* ACRShowCardTarget.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6B1147D91F32F922008846EC /* ACRShowCardTarget.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6B1147D71F32F922008846EC /* ACRShowCardTarget.mm */; }; 6B3787B720CA00D300015401 /* ACRUILabel.h in Headers */ = {isa = PBXBuildFile; fileRef = F4F44B6A203FA8EF00A2F24C /* ACRUILabel.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6B3787BA20CB3E0E00015401 /* ACRContentHoldingUIScrollView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6B3787B820CB3E0E00015401 /* ACRContentHoldingUIScrollView.mm */; }; + 6B3787BB20CB3E0E00015401 /* ACRContentHoldingUIScrollView.h in Headers */ = {isa = PBXBuildFile; fileRef = 6B3787B920CB3E0E00015401 /* ACRContentHoldingUIScrollView.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6B6840F91F25EC2D008A933F /* ACRInputChoiceSetRenderer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6B6840F71F25EC2D008A933F /* ACRInputChoiceSetRenderer.mm */; }; 6B7B1A9720BE2CBC00260731 /* ACRUIImageView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6B7B1A9520BE2CBB00260731 /* ACRUIImageView.mm */; }; 6B7B1A9820BE2CBC00260731 /* ACRUIImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 6B7B1A9620BE2CBC00260731 /* ACRUIImageView.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -255,6 +257,8 @@ 6B1147D01F32E53A008846EC /* ACRActionDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ACRActionDelegate.h; sourceTree = ""; }; 6B1147D61F32F922008846EC /* ACRShowCardTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ACRShowCardTarget.h; sourceTree = ""; }; 6B1147D71F32F922008846EC /* ACRShowCardTarget.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ACRShowCardTarget.mm; sourceTree = ""; }; + 6B3787B820CB3E0E00015401 /* ACRContentHoldingUIScrollView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ACRContentHoldingUIScrollView.mm; sourceTree = ""; }; + 6B3787B920CB3E0E00015401 /* ACRContentHoldingUIScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ACRContentHoldingUIScrollView.h; sourceTree = ""; }; 6B6840F61F25EC2D008A933F /* ACRInputChoiceSetRenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ACRInputChoiceSetRenderer.h; sourceTree = ""; }; 6B6840F71F25EC2D008A933F /* ACRInputChoiceSetRenderer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ACRInputChoiceSetRenderer.mm; sourceTree = ""; }; 6B7B1A9520BE2CBB00260731 /* ACRUIImageView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ACRUIImageView.mm; sourceTree = ""; }; @@ -749,11 +753,13 @@ F42979351F3007DF00E89914 /* Layouts */ = { isa = PBXGroup; children = ( + F4C1F5ED1F2BB2810018CB78 /* ACRIContentHoldingView.h */, F401A87D1F1045CA006D7AF2 /* ACRContentHoldingUIView.h */, F401A87E1F1045CA006D7AF2 /* ACRContentHoldingUIView.mm */, - F4D33EA41F06F41B00941E44 /* ACRSeparator.mm */, + 6B3787B920CB3E0E00015401 /* ACRContentHoldingUIScrollView.h */, + 6B3787B820CB3E0E00015401 /* ACRContentHoldingUIScrollView.mm */, F4D33EA61F06F44C00941E44 /* ACRSeparator.h */, - F4C1F5ED1F2BB2810018CB78 /* ACRIContentHoldingView.h */, + F4D33EA41F06F41B00941E44 /* ACRSeparator.mm */, F4FE45681F196F3D0071D9E5 /* ACRContentStackView.h */, F4FE45691F196F3D0071D9E5 /* ACRContentStackView.mm */, F4FE456C1F1985200071D9E5 /* ACRColumnSetView.h */, @@ -871,7 +877,6 @@ F4D0694C205B27EA003645E4 /* ACRViewPrivate.h in Headers */, F42E51791FEC3840008F9642 /* MarkDownParser.h in Headers */, F4F6BA3C204F3109003741B6 /* ACRAggregateTarget.h in Headers */, - 6B1147D81F32F922008846EC /* ACRShowCardTarget.h in Headers */, F4CA74A12016B3B9002041DF /* ACRLongPressGestureRecognizerEventHandler.h in Headers */, F4FA2732201FF941005989F9 /* ACRLongPressGestureRecognizerFactory.h in Headers */, F4D33EA71F06F44C00941E44 /* ACRSeparator.h in Headers */, @@ -884,6 +889,8 @@ F401A8771F0DB69B006D7AF2 /* ACRImageSetUICollectionView.h in Headers */, F43110471F357487001AAE30 /* ACRToggleInputDataSource.h in Headers */, F4F44BA1204CED2400A2F24C /* ACRCustomRenderer.h in Headers */, + 6B1147D81F32F922008846EC /* ACRShowCardTarget.h in Headers */, + 6B3787BB20CB3E0E00015401 /* ACRContentHoldingUIScrollView.h in Headers */, F495FC0B2022A18F0093D4DE /* ACRChoiceSetViewDataSource.h in Headers */, F4C1F5E81F2ABB3C0018CB78 /* ACRIBaseActionElementRenderer.h in Headers */, F4C1F5EB1F2ABD6B0018CB78 /* ACRBaseActionElementRenderer.h in Headers */, @@ -1102,6 +1109,7 @@ F42C2F4A20351954008787B0 /* (null) in Sources */, F4CA74A02016B3B9002041DF /* ACRLongPressGestureRecognizerEventHandler.mm in Sources */, F42741171EF895AB00399FBB /* ACRTextBlockRenderer.mm in Sources */, + 6B3787BA20CB3E0E00015401 /* ACRContentHoldingUIScrollView.mm in Sources */, F44873231EE2261F00FCAFAE /* TextBlock.cpp in Sources */, F44872F91EE2261F00FCAFAE /* BaseCardElement.cpp in Sources */, F427410B1EF864A900399FBB /* ACRBaseCardElementRenderer.mm in Sources */, diff --git a/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards/ACRColumnSetView.mm b/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards/ACRColumnSetView.mm index 7db753da2e..8c5d48a480 100644 --- a/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards/ACRColumnSetView.mm +++ b/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards/ACRColumnSetView.mm @@ -9,12 +9,12 @@ @implementation ACRColumnSetView -- (void)config +- (void)config:(nullable NSDictionary *)attributes { - [super config]; super.stackView.axis = UILayoutConstraintAxisHorizontal; super.stackView.distribution = UIStackViewDistributionFill; super.stackView.alignment = UIStackViewAlignmentLeading; + [super config:attributes]; } - (void)addArrangedSubview:(UIView* )view @@ -25,7 +25,7 @@ - (void)addArrangedSubview:(UIView* )view } - (void)adjustHuggingForLastElement -{ +{ if([super.stackView.arrangedSubviews count]) [[super.stackView.arrangedSubviews objectAtIndex:[super.stackView.arrangedSubviews count ] - 1] setContentHuggingPriority:UILayoutPriorityFittingSizeLevel forAxis:UILayoutConstraintAxisHorizontal]; } diff --git a/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards/ACRColumnView.mm b/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards/ACRColumnView.mm index 07253498c1..7b39f8b681 100644 --- a/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards/ACRColumnView.mm +++ b/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards/ACRColumnView.mm @@ -9,11 +9,11 @@ @implementation ACRColumnView -- (void)config +- (void)config:(nullable NSDictionary *)attributes { - [super config]; super.stackView.axis = UILayoutConstraintAxisVertical; super.stackView.distribution = UIStackViewDistributionFill; + [super config:attributes]; } - (void)addArrangedSubview:(UIView *)view diff --git a/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards/ACRContentHoldingUIScrollView.h b/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards/ACRContentHoldingUIScrollView.h new file mode 100644 index 0000000000..064bf0b169 --- /dev/null +++ b/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards/ACRContentHoldingUIScrollView.h @@ -0,0 +1,12 @@ +// +// ACRContentHoldingUIScrollView +// ACRContentHoldingUIScrollView.h +// +// Copyright © 2018 Microsoft. All rights reserved. +// + +#import + +@interface ACRContentHoldingUIScrollView: UIScrollView + +@end diff --git a/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards/ACRContentHoldingUIScrollView.mm b/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards/ACRContentHoldingUIScrollView.mm new file mode 100644 index 0000000000..c1cb36ec58 --- /dev/null +++ b/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards/ACRContentHoldingUIScrollView.mm @@ -0,0 +1,17 @@ +// +// ACRContentHoldingUIScrollView +// ACRContentHoldingUIScrollView.mm +// +// Copyright © 2018 Microsoft. All rights reserved. +// + +#import "ACRContentHoldingUIScrollView.h" + +@implementation ACRContentHoldingUIScrollView + +- (CGSize)intrinsicContentSize +{ + return self.frame.size; +} + +@end diff --git a/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards/ACRContentStackView.h b/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards/ACRContentStackView.h index 215e956fd5..fff0f77479 100644 --- a/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards/ACRContentStackView.h +++ b/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards/ACRContentStackView.h @@ -10,15 +10,17 @@ @interface ACRContentStackView:UIView -@property UIStackView* stackView; +@property (nonnull) UIStackView* stackView; -- (instancetype)initWithFrame:(CGRect)frame; +- (instancetype _Nonnull)initWithFrame:(CGRect)frame; -- (void)addArrangedSubview:(UIView *)view; +- (instancetype _Nonnull)initWithFrame:(CGRect)frame attributes:(nullable NSDictionary *)attributes; -- (void)config; +- (void)addArrangedSubview:(nonnull UIView *)view; + +- (void)config:(nullable NSDictionary *)attributes; - (void)adjustHuggingForLastElement; -- (void)addTarget:(NSObject *)target; +- (void)addTarget:(nonnull NSObject *)target; @end diff --git a/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards/ACRContentStackView.mm b/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards/ACRContentStackView.mm index f5c4219b61..ef7ab0903a 100644 --- a/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards/ACRContentStackView.mm +++ b/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards/ACRContentStackView.mm @@ -39,15 +39,17 @@ - (instancetype)initWithStyle:(ACRContainerStyle)style return self; } -- (instancetype)initWithFrame:(CGRect)frame -{ +- (instancetype)initWithFrame:(CGRect)frame attributes:(nullable NSDictionary *)attributes{ self = [super initWithFrame:CGRectMake(0,0,frame.size.width,0)]; - if(self) - { + if(self) { _stackView = [[UIStackView alloc] initWithFrame:frame]; - [self config]; + [self config:attributes]; } - + return self; +} +- (instancetype)initWithFrame:(CGRect)frame +{ + self = [self initWithFrame:CGRectMake(0,0,frame.size.width,0) attributes:nil]; return self; } @@ -58,7 +60,7 @@ - (instancetype)initWithCoder:(NSCoder *)aDecoder if (self) { _stackView = [[UIStackView alloc] init]; - [self config]; + [self config:nil]; } return self; @@ -112,7 +114,7 @@ - (void)setBorderThicknessWithHostConfig:(std::shared_ptr const &)co [[self layer] setBorderWidth:borderWidth]; } -- (void)config +- (void)config:(nullable NSDictionary *)attributes { if(!self.stackView){ return; @@ -124,6 +126,21 @@ - (void)config _targets = [[NSMutableArray alloc] init]; _showcardTargets = [[NSMutableArray alloc] init]; + + if(attributes){ + NSNumber *distribAttrib = attributes[@"distribution"]; + if(distribAttrib){ + self.stackView.distribution = (UIStackViewDistribution)[distribAttrib integerValue]; + } + NSNumber *alignAttrib = attributes[@"alignment"]; + if(alignAttrib){ + self.stackView.alignment = (UIStackViewAlignment)[alignAttrib integerValue]; + } + NSNumber *spacingAttrib = attributes[@"spacing"]; + if(spacingAttrib){ + self.stackView.spacing = [spacingAttrib floatValue]; + } + } } - (CGSize)intrinsicContentSize diff --git a/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards/ACRRenderer.mm b/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards/ACRRenderer.mm index ca2b9490f9..49b75fdccb 100644 --- a/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards/ACRRenderer.mm +++ b/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards/ACRRenderer.mm @@ -17,6 +17,7 @@ #import "ACRSeparator.h" #import "ACRViewPrivate.h" #import "ACRViewController.h" +#import "ACRContentHoldingUIScrollView.h" using namespace AdaptiveCards; @@ -98,18 +99,19 @@ + (UIView *)renderWithAdaptiveCards:(std::shared_ptr const &)adapt { ACRRegistration *reg = [ACRRegistration getInstance]; UIView *childview = nil; - UILayoutConstraintAxis axis = UILayoutConstraintAxisVertical; + NSDictionary *attributes = + @{@"spacing":[NSNumber numberWithInt:[config getHostConfig]->actions.buttonSpacing], + @"distribution":[NSNumber numberWithInt:UIStackViewDistributionFillEqually]}; + if(ActionsOrientation::Horizontal == [config getHostConfig]->actions.actionsOrientation){ - childview = [[ACRColumnSetView alloc] initWithFrame:CGRectMake(0, 0, superview.frame.size.width, superview.frame.size.height)]; - axis = UILayoutConstraintAxisHorizontal; + childview = [[ACRColumnSetView alloc] initWithFrame:CGRectMake(0, 0, superview.frame.size.width, superview.frame.size.height) attributes:attributes]; } else{ - childview = [[ACRColumnView alloc] initWithFrame:CGRectMake(0, 0, superview.frame.size.width, superview.frame.size.height)]; + childview = [[ACRColumnView alloc] initWithFrame:CGRectMake(0, 0, superview.frame.size.width, superview.frame.size.height) attributes:attributes]; } ACOBaseActionElement *acoElem = [[ACOBaseActionElement alloc] init]; - [superview addArrangedSubview:childview]; - + float accumulatedWidth = 0, accumulatedHeight = 0, spacing = [config getHostConfig]->actions.buttonSpacing, maxWidth = 0, maxHeight = 0; for(const auto &elem:elems){ ACRBaseActionElementRenderer *actionRenderer = [reg getActionRenderer:[NSNumber numberWithInt:(int)elem->GetElementType()]]; @@ -121,12 +123,55 @@ + (UIView *)renderWithAdaptiveCards:(std::shared_ptr const &)adapt [acoElem setElem:elem]; UIButton *button = [actionRenderer renderButton:rootView inputs:inputs superview:superview baseActionElement:acoElem hostConfig:config]; + + accumulatedWidth += [button intrinsicContentSize].width; + accumulatedHeight += [button intrinsicContentSize].height; + maxWidth = MAX(maxWidth, [button intrinsicContentSize].width); + maxHeight = MAX(maxHeight, [button intrinsicContentSize].height); + [childview addArrangedSubview:button]; - [ACRSeparator renderSeparationWithFrame:CGRectMake(0,0,[config getHostConfig]->actions.buttonSpacing, [config getHostConfig]->actions.buttonSpacing) - superview:childview axis:axis]; } + float contentWidth = accumulatedWidth, contentHeight = accumulatedHeight; [childview adjustHuggingForLastElement]; + if(ActionsOrientation::Horizontal == [config getHostConfig]->actions.actionsOrientation){ + contentWidth += (elems.size() - 1) * spacing; + contentHeight = maxHeight; + } else { + contentHeight += (elems.size() - 1) * spacing; + contentWidth = maxWidth; + } + childview.frame = CGRectMake(0, 0, contentWidth, contentHeight); + + ACRContentHoldingUIScrollView *containingView = [[ACRContentHoldingUIScrollView alloc] initWithFrame:CGRectMake(0, 0, superview.frame.size.width, contentHeight)]; + containingView.translatesAutoresizingMaskIntoConstraints = NO; + [superview addArrangedSubview:containingView]; + [containingView addSubview:childview]; + [NSLayoutConstraint constraintWithItem:containingView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:childview attribute:NSLayoutAttributeTop multiplier:1.0 constant:0].active = YES; + [NSLayoutConstraint constraintWithItem:containingView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:childview attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0].active = YES; + [NSLayoutConstraint constraintWithItem:containingView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:childview attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0].active = YES; + [NSLayoutConstraint constraintWithItem:containingView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:childview attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:0].active = YES; + NSLayoutConstraint *hConstraint = [NSLayoutConstraint constraintWithItem:childview attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:containingView attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0]; + NSLayoutConstraint *vConstraint = [NSLayoutConstraint constraintWithItem:childview attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:containingView attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0]; + + hConstraint.active = YES; + vConstraint.active = YES; + + if(ActionsOrientation::Horizontal == [config getHostConfig]->actions.actionsOrientation){ + hConstraint.priority = UILayoutPriorityDefaultLow; + if(contentWidth > superview.frame.size.width){ + containingView.showsHorizontalScrollIndicator = YES; + } else + { + if([config getHostConfig]->actions.actionAlignment == ActionAlignment::Stretch){ + [NSLayoutConstraint constraintWithItem:containingView attribute:NSLayoutAttributeWidth + relatedBy:NSLayoutRelationEqual toItem:childview + attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0].active = YES; + } + } + } else { + vConstraint.priority = UILayoutPriorityDefaultLow; + } return childview; } diff --git a/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards/ACRShowCardTarget.mm b/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards/ACRShowCardTarget.mm index c388b6a932..a3b01129ae 100644 --- a/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards/ACRShowCardTarget.mm +++ b/source/ios/AdaptiveCards/AdaptiveCards/AdaptiveCards/ACRShowCardTarget.mm @@ -51,7 +51,7 @@ - (void)createShowCard:(NSMutableArray*)inputs if(!inputs){ inputs = [[NSMutableArray alloc] init]; } - ACRColumnView *containingView = [[ACRColumnView alloc] init]; + ACRColumnView *containingView = [[ACRColumnView alloc] initWithFrame:_rootView.frame]; UIView *adcView = [ACRRenderer renderWithAdaptiveCards:_adaptiveCard inputs:inputs context:_rootView