Skip to content

Commit

Permalink
replace SDAutoLayout with UIStackView
Browse files Browse the repository at this point in the history
  • Loading branch information
Piasy committed Feb 24, 2025
1 parent fb59111 commit dc20470
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 117 deletions.
1 change: 0 additions & 1 deletion example/iosApp/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,5 @@ target 'iosApp' do
platform :ios, '14.0'
pod 'kmp_webrtc', :path => '../../kmp-webrtc/kmp_webrtc.podspec'
pod 'WebRTC', :path => '../../libs/apple/WebRTC.podspec'
pod 'SDAutoLayout', '~> 2.2.1'
pod 'kmp_xlog', '~> 1.3.1'
end
157 changes: 81 additions & 76 deletions example/iosApp/iosApp/CallViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
#import "ARDSettingsModel.h"
#import "ARDToast.h"

@import SDAutoLayout;
@import WebRTC;
@import kmp_webrtc;

Expand All @@ -40,25 +39,24 @@ @interface CallViewController () <Kmp_webrtcPeerConnectionClientCallback, CFAudi
@implementation CallViewController {
ARDSettingsModel* _settingsModel;
bool _isLandscape;

Kmp_webrtcObjCPeerConnectionClientFactory* _pcClientFactory;
id<Kmp_webrtcPeerConnectionClient> _pcClient;
NSTimer* _statsTimer;
CFAudioMixer* _mixer;

UIView* _rootLayout;

CFEAGLVideoView* _remoteRenderer;
CFEAGLVideoView* _localRenderer;

UIButton* _leaveButton;
UIButton* _recordButton;
UIButton* _mixerButton;
UIButton* _switchCameraButton;

bool _recording;
bool _mixingMusic;
bool _videoEnabled;

bool _sendLastFrame;
bool _left;
}
Expand All @@ -77,18 +75,47 @@ - (UIInterfaceOrientationMask)supportedInterfaceOrientations {
: UIInterfaceOrientationMaskPortrait;
}

- (void)loadView {
CGSize fc = [UIScreen mainScreen].bounds.size;
CGFloat fcWidth = _isLandscape ? fc.height : fc.width;
CGFloat fcHeight = _isLandscape ? fc.width : fc.height;
- (void)viewDidLoad {
[super viewDidLoad];

self.view =
[[UIView alloc] initWithFrame:CGRectMake(0, 0, fcWidth, fcHeight)];
_localRenderer =
[[CFEAGLVideoView alloc] initWithFrame:CGRectZero
andUid:@"test_local"
andScaleType:CF_SCALE_TYPE_CENTER_CROP];
_localRenderer.mirror = YES;
_localRenderer.autoresizingMask =
UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

_remoteRenderer =
[[CFEAGLVideoView alloc] initWithFrame:CGRectZero
andUid:@"test_remote"
andScaleType:CF_SCALE_TYPE_CENTER_CROP];
_remoteRenderer.mirror = NO;
_remoteRenderer.autoresizingMask =
UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

_rootLayout = [[UIView alloc] init];
[self.view addSubview:_rootLayout];
_rootLayout.sd_layout.widthRatioToView(self.view, 1)
.heightRatioToView(self.view, 1);
UIView* localWrapper = [[UIView alloc] init];
[localWrapper addSubview:_localRenderer];
UIView* remoteWrapper = [[UIView alloc] init];
[remoteWrapper addSubview:_remoteRenderer];

UIStackView *mainStackView = [[UIStackView alloc] init];
mainStackView.axis = UILayoutConstraintAxisVertical;
mainStackView.distribution = UIStackViewDistributionFillEqually;
mainStackView.alignment = UIStackViewAlignmentFill;
mainStackView.spacing = 0;
mainStackView.translatesAutoresizingMaskIntoConstraints = NO;

[mainStackView addArrangedSubview:localWrapper];
[mainStackView addArrangedSubview:remoteWrapper];
[self.view addSubview:mainStackView];

[NSLayoutConstraint activateConstraints:@[
[mainStackView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[mainStackView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[mainStackView.topAnchor constraintEqualToAnchor:self.view.topAnchor],
[mainStackView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor]
]];

_recordButton = [UIButton buttonWithType:UIButtonTypeSystem];
[_recordButton setTitle:_recording ? @"stop record" : @"start record"
Expand All @@ -97,11 +124,6 @@ - (void)loadView {
[_recordButton addTarget:self
action:@selector(onRecord:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_recordButton];
_recordButton.sd_layout.widthIs(120)
.heightIs(20)
.bottomSpaceToView(self.view, 30)
.leftSpaceToView(self.view, 10);

_mixerButton = [UIButton buttonWithType:UIButtonTypeSystem];
[_mixerButton setTitle:_mixingMusic ? @"stop mixer" : @"start mixer"
Expand All @@ -110,89 +132,72 @@ - (void)loadView {
[_mixerButton addTarget:self
action:@selector(onMixer:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_mixerButton];
_mixerButton.sd_layout.widthIs(120)
.heightIs(20)
.bottomEqualToView(_recordButton)
.leftSpaceToView(_recordButton, 10);

_leaveButton = [UIButton buttonWithType:UIButtonTypeSystem];
[_leaveButton setTitle:@"Leave" forState:UIControlStateNormal];
_leaveButton.titleLabel.font = [UIFont systemFontOfSize:20.0];
[_leaveButton addTarget:self
action:@selector(onLeaveCall:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_leaveButton];
_leaveButton.sd_layout.widthIs(80)
.heightIs(20)
.bottomEqualToView(_recordButton)
.leftSpaceToView(_mixerButton, 10);

UIStackView *ops1 = [[UIStackView alloc] init];
ops1.axis = UILayoutConstraintAxisHorizontal;
ops1.distribution = UIStackViewDistributionFillEqually;
ops1.alignment = UIStackViewAlignmentFill;
ops1.spacing = 0;
ops1.translatesAutoresizingMaskIntoConstraints = NO;

[ops1 addArrangedSubview:_recordButton];
[ops1 addArrangedSubview:_mixerButton];
[ops1 addArrangedSubview:_leaveButton];
[self.view addSubview:ops1];

[NSLayoutConstraint activateConstraints:@[
[ops1.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[ops1.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[ops1.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor],
[ops1.heightAnchor constraintGreaterThanOrEqualToConstant:30]
]];

_switchCameraButton = [UIButton buttonWithType:UIButtonTypeSystem];
[_switchCameraButton setTitle:@"FRONT" forState:UIControlStateNormal];
_switchCameraButton.titleLabel.font = [UIFont systemFontOfSize:20.0];
[_switchCameraButton addTarget:self
action:@selector(onSwitchCamera:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_switchCameraButton];
_switchCameraButton.sd_layout.widthIs(80)
.heightIs(20)
.leftEqualToView(_recordButton)
.bottomSpaceToView(_recordButton, 20);

UIButton* videoButton = [UIButton buttonWithType:UIButtonTypeSystem];
[videoButton setTitle:@"Video" forState:UIControlStateNormal];
videoButton.titleLabel.font = [UIFont systemFontOfSize:20.0];
[videoButton addTarget:self
action:@selector(onToggleVideo:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:videoButton];
videoButton.sd_layout.widthIs(80)
.heightIs(20)
.bottomEqualToView(_switchCameraButton)
.leftSpaceToView(_switchCameraButton, 10);

UIButton* sendLastFrameButton = [UIButton buttonWithType:UIButtonTypeSystem];
[sendLastFrameButton setTitle:@"SLF" forState:UIControlStateNormal];
sendLastFrameButton.titleLabel.font = [UIFont systemFontOfSize:20.0];
[sendLastFrameButton addTarget:self
action:@selector(onToggleSendLastFrame:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:sendLastFrameButton];
sendLastFrameButton.sd_layout.widthIs(80)
.heightIs(20)
.bottomEqualToView(_switchCameraButton)
.leftSpaceToView(videoButton, 10);

_localRenderer =
[[CFEAGLVideoView alloc] initWithFrame:CGRectZero
andUid:@"test_local"
andScaleType:CF_SCALE_TYPE_CENTER_CROP];
_localRenderer.mirror = YES;
_localRenderer.autoresizingMask =
UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

_remoteRenderer =
[[CFEAGLVideoView alloc] initWithFrame:CGRectZero
andUid:@"test_remote"
andScaleType:CF_SCALE_TYPE_CENTER_CROP];
_remoteRenderer.mirror = NO;
_remoteRenderer.autoresizingMask =
UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

UIView* wrapper = [[UIView alloc] init];
[_rootLayout insertSubview:wrapper atIndex:0];
wrapper.sd_layout.widthRatioToView(_rootLayout, 1)
.heightRatioToView(_rootLayout, 0.5)
.topEqualToView(_rootLayout);
[wrapper addSubview:_localRenderer];

wrapper = [[UIView alloc] init];
[_rootLayout insertSubview:wrapper atIndex:0];
wrapper.sd_layout.widthRatioToView(_rootLayout, 1)
.heightRatioToView(_rootLayout, 0.5)
.bottomEqualToView(_rootLayout);
[wrapper addSubview:_remoteRenderer];
UIStackView *ops2 = [[UIStackView alloc] init];
ops2.axis = UILayoutConstraintAxisHorizontal;
ops2.distribution = UIStackViewDistributionFillEqually;
ops2.alignment = UIStackViewAlignmentFill;
ops2.spacing = 0;
ops2.translatesAutoresizingMaskIntoConstraints = NO;

[ops2 addArrangedSubview:_switchCameraButton];
[ops2 addArrangedSubview:videoButton];
[ops2 addArrangedSubview:sendLastFrameButton];
[self.view addSubview:ops2];

[NSLayoutConstraint activateConstraints:@[
[ops2.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[ops2.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[ops2.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor constant:-60],
[ops2.heightAnchor constraintGreaterThanOrEqualToConstant:30]
]];

[self startLoopback];
}
Expand Down
96 changes: 56 additions & 40 deletions example/iosApp/iosApp/HallViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
#import "CallViewController.h"
#import "ARDToast.h"

@import SDAutoLayout;
@import WebRTC;

static NSString* const barButtonImageString = @"ic_settings_black_24dp.png";
Expand All @@ -22,57 +21,74 @@ @implementation HallViewController {

- (void)viewDidLoad {
[super viewDidLoad];

self.title = @"kmp-webrtc";
self.view.backgroundColor = [UIColor whiteColor];
[self addSettingsBarButton];

UIButton* create = [UIButton buttonWithType:UIButtonTypeSystem];
[create setTitle:@"loopback" forState:UIControlStateNormal];
create.titleLabel.font = [UIFont systemFontOfSize:20];
[self.view addSubview:create];
create.sd_layout.widthIs(180)
.heightIs(20)
.topSpaceToView(self.view, 30)
.centerXEqualToView(self.view);

[create addTarget:self
action:@selector(onLoopback:)
forControlEvents:UIControlEventTouchUpInside];

UITableViewCell* audioOnlyCell =
[[UITableViewCell alloc] initWithFrame:CGRectZero];
audioOnlyCell.selectionStyle = UITableViewCellSelectionStyleNone;
_audioOnlySwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
audioOnlyCell.accessoryView = _audioOnlySwitch;
audioOnlyCell.textLabel.text = @"Audio only";
[self.view addSubview:audioOnlyCell];
audioOnlyCell.sd_layout.widthIs(180)
.heightRatioToView(create, 1)
.topSpaceToView(create, 20)
.centerXEqualToView(self.view);

UIButton* loopback = [UIButton buttonWithType:UIButtonTypeSystem];
[loopback setTitle:@"loopback" forState:UIControlStateNormal];
[loopback addTarget:self
action:@selector(onLoopback:)
forControlEvents:UIControlEventTouchUpInside];
loopback.titleLabel.font = [UIFont systemFontOfSize:20];

UIStackView *switchStackView = [[UIStackView alloc] init];
switchStackView.axis = UILayoutConstraintAxisHorizontal;
switchStackView.distribution = UIStackViewDistributionFillProportionally;
switchStackView.spacing = 10;
UILabel *switchLabel = [[UILabel alloc] init];
switchLabel.text = @"Audio only";
switchLabel.font = [UIFont systemFontOfSize:20];
[switchStackView addArrangedSubview:switchLabel];
_audioOnlySwitch = [[UISwitch alloc] init];
[switchStackView addArrangedSubview:_audioOnlySwitch];

UIButton* shareLog = [UIButton buttonWithType:UIButtonTypeSystem];
[shareLog setTitle:@"share log" forState:UIControlStateNormal];
shareLog.titleLabel.font = [UIFont systemFontOfSize:20];
[self.view addSubview:shareLog];
shareLog.sd_layout.widthIs(180)
.heightRatioToView(create, 1)
.topSpaceToView(audioOnlyCell, 20)
.centerXEqualToView(self.view);

[shareLog addTarget:self
action:@selector(onShareLog:)
forControlEvents:UIControlEventTouchUpInside];
shareLog.titleLabel.font = [UIFont systemFontOfSize:20];

UILabel* version = [[UILabel alloc] initWithFrame:CGRectZero];
version.text = [NSString stringWithFormat:@"kmp-webrtc %@", [CFPeerConnectionClient versionName]];
version.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:version];
version.sd_layout.widthIs(250)
.heightRatioToView(create, 1)
.topSpaceToView(shareLog, 10)
.centerXEqualToView(self.view);
version.font = [UIFont systemFontOfSize:20];

UIStackView *stackView = [[UIStackView alloc] init];
stackView.axis = UILayoutConstraintAxisVertical;
stackView.alignment = UIStackViewAlignmentLeading;
stackView.distribution = UIStackViewDistributionFillEqually;
stackView.spacing = 10;

[stackView addArrangedSubview:loopback];
[stackView addArrangedSubview:switchStackView];
[stackView addArrangedSubview:shareLog];
[stackView addArrangedSubview:version];
[self.view addSubview:stackView];

// 使用 Auto Layout 约束 StackView 的位置和大小
stackView.translatesAutoresizingMaskIntoConstraints = NO;
// 水平居中
NSLayoutConstraint *centerXConstraint =
[NSLayoutConstraint constraintWithItem:stackView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0];
// 距离顶部 50
NSLayoutConstraint *topConstraint =
[NSLayoutConstraint constraintWithItem:stackView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.view.safeAreaLayoutGuide
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:50];
// 激活约束
[NSLayoutConstraint activateConstraints:@[centerXConstraint, topConstraint]];
}

- (void)viewDidAppear:(BOOL)animated {
Expand Down

0 comments on commit dc20470

Please sign in to comment.