Add ability to set iOS artboard volume through RiveModel

Updates the `RiveModel` API with the ability to set and get the volume for the currently set artboard. Any new artboards will default to use the last-set volume of the model. A volume default of 1.0 is set to match rive-cpp's default. `RiveArtboard` is also updated to forward volume calls to the artboard instance, exposing a new `volume` property.

There's an open question whether this belongs in `RiveViewModel`, or `RiveModel`, but I went for `RiveModel` since there's a direct reference to the artboard within the model itself, and an indirect reference through the view model (model?.artboard)

Diffs=
a31cd9761 Add ability to set iOS artboard volume through RiveModel (#7658)

Co-authored-by: David Skuza <david@rive.app>
This commit is contained in:
dskuza
2024-07-23 18:17:06 +00:00
parent 164e65cce4
commit e77bda6ffa
8 changed files with 87 additions and 5 deletions

View File

@@ -1 +1 @@
114da4e39ba61dd337e8f6f47c1c7b2fb2223915
a31cd9761efdc411d4c462f065e37d84af04984c

View File

@@ -20,6 +20,10 @@ struct SwiftAudioAssets: DismissableView {
);
var body: some View {
riveViewModel.view()
riveViewModel
.view()
.onAppear {
riveViewModel.riveModel?.volume = 0.01
}
}
}

View File

@@ -95,6 +95,7 @@
E5964A982A9697B600140479 /* RiveEvent.mm in Sources */ = {isa = PBXBuildFile; fileRef = E5964A972A9697B600140479 /* RiveEvent.mm */; };
E599DCF92AAFA06100D1E49A /* rating_animation.riv in Resources */ = {isa = PBXBuildFile; fileRef = E599DCF82AAFA06100D1E49A /* rating_animation.riv */; };
E599DCFA2AAFA06100D1E49A /* rating_animation.riv in Resources */ = {isa = PBXBuildFile; fileRef = E599DCF82AAFA06100D1E49A /* rating_animation.riv */; };
F28DE4532C5002D900F3C379 /* RiveModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F28DE4522C5002D900F3C379 /* RiveModelTests.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -198,6 +199,7 @@
E5964A952A965A9300140479 /* RiveEvent.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; path = RiveEvent.h; sourceTree = "<group>"; };
E5964A972A9697B600140479 /* RiveEvent.mm */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; path = RiveEvent.mm; sourceTree = "<group>"; };
E599DCF82AAFA06100D1E49A /* rating_animation.riv */ = {isa = PBXFileReference; lastKnownFileType = file; name = rating_animation.riv; path = "Example-iOS/Assets/rating_animation.riv"; sourceTree = SOURCE_ROOT; };
F28DE4522C5002D900F3C379 /* RiveModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RiveModelTests.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -389,6 +391,7 @@
04BE542C264C1A3300427B39 /* RiveDelegatesTest.swift */,
C38BB5F528762B720039E385 /* RiveStateMachineTest.swift */,
041265252B0CB41E009400EC /* OutOfBandAssetTest.mm */,
F28DE4522C5002D900F3C379 /* RiveModelTests.swift */,
);
path = Tests;
sourceTree = "<group>";
@@ -594,6 +597,7 @@
04BE541C264A90D600427B39 /* RiveAnimationLoadTest.mm in Sources */,
C9C73EE024FC478900EF9516 /* RiveRuntimeTests.mm in Sources */,
04BE5413264943BB00427B39 /* util.mm in Sources */,
F28DE4532C5002D900F3C379 /* RiveModelTests.swift in Sources */,
04BE54112649434900427B39 /* RiveFileLoadTest.mm in Sources */,
C38BB5F628762B720039E385 /* RiveStateMachineTest.swift in Sources */,
04BE5418264A818F00427B39 /* RiveAnimationConfigurationsTest.mm in Sources */,

View File

@@ -319,4 +319,14 @@ static int artInstanceCount = 0;
}
}
- (float)volume
{
return _artboardInstance->volume();
}
- (void)setVolume:(float)volume
{
_artboardInstance->volume(volume);
}
@end

View File

@@ -23,6 +23,8 @@ NS_ASSUME_NONNULL_BEGIN
//
@interface RiveArtboard : NSObject
@property(nonatomic, assign) float volume NS_REFINED_FOR_SWIFT;
- (NSString*)name;
- (CGRect)bounds;

View File

@@ -27,7 +27,27 @@ import Combine
public init(webURL: String, delegate: RiveFileDelegate, loadCdn: Bool) {
riveFile = RiveFile(httpUrl: webURL, loadCdn:loadCdn, with: delegate)!
}
// rive-cpp defaults the volume to 1.0f
// This value is used if there is no artboard,
// and will be used to set the volume once a model is configured (with an artboard)
private var _volume: Float = 1
/// The volume of the current artboard, if available. Defaults to 1.
@objc open var volume: Float {
get {
if let volume = artboard?.__volume {
return volume
}
return _volume
}
set {
_volume = newValue
artboard?.__volume = newValue
}
}
// MARK: - Setters
/// Sets a new Artboard and makes the current StateMachine and Animation nil
@@ -36,6 +56,7 @@ import Combine
stateMachine = nil
animation = nil
artboard = try riveFile.artboard(fromName: name)
artboard.__volume = _volume
}
catch { throw RiveModelError.invalidArtboard("Name \(name) not found") }
}
@@ -47,11 +68,15 @@ import Combine
stateMachine = nil
animation = nil
artboard = try riveFile.artboard(from: index)
artboard.__volume = _volume
}
catch { throw RiveModelError.invalidArtboard("Index \(index) not found") }
} else {
// This tries to find the 'default' Artboard
do { artboard = try riveFile.artboard() }
do {
artboard = try riveFile.artboard()
artboard.__volume = _volume
}
catch { throw RiveModelError.invalidArtboard("No Default Artboard") }
}
}

View File

@@ -180,7 +180,6 @@ import Combine
didSet { riveView?.fit = fit }
}
open var alignment: RiveAlignment = .center {
didSet { riveView?.alignment = alignment }
}

View File

@@ -0,0 +1,38 @@
//
// RiveModelTests.swift
// RiveRuntimeTests
//
// Created by David Skuza on 7/23/24.
// Copyright © 2024 Rive. All rights reserved.
//
import XCTest
@testable import RiveRuntime
class RiveModelTests: XCTestCase {
func test_volume() throws {
let file = try RiveFile(testfileName: "multipleartboards")
let model = RiveModel(riveFile: file)
XCTAssertEqual(model.volume, 1)
do {
try model.setArtboard()
model.volume = 0.5
XCTAssertEqual(model.volume, 0.5)
XCTAssertEqual(model.artboard?.__volume, 0.5)
}
do {
try model.setArtboard("artboard2")
XCTAssertEqual(model.volume, 0.5)
XCTAssertEqual(model.artboard?.__volume, 0.5)
model.volume = 0
XCTAssertEqual(model.volume, 0)
XCTAssertEqual(model.artboard?.__volume, 0)
}
}
}