首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将旧式视图(音频单元视图)合并到自动布局中

将旧式视图(音频单元视图)合并到自动布局中
EN

Stack Overflow用户
提问于 2020-06-22 17:23:30
回答 1查看 244关注 0票数 1

我想将音频单元创建的自定义视图嵌入到使用自动布局的窗口中。在尝试了几十种组合后,我仍然没有找到一种方法来处理大量的音频单元。

目标是创建一个以音频单元视图作为子视图的容器NSView对象,并以容器的大小与AU视图的大小匹配的方式设置约束,包括当AU视图调整自身大小时。容器应该将translatesAutoresizingMaskIntoConstraints设置为NO,这样它就可以很好地处理窗口的其余部分。

我的第一个尝试是创建两个约束,简单地强制两个视图(容器和AU)的大小相等。这会失败,因为AU视图随后会折叠到非常小的尺寸。

另一种尝试是为容器视图创建固定大小约束,这些约束被初始化为与AU视图匹配,侦听AU视图的NSViewFrameDidChangeNotification,并根据需要调整固定大小。只要AU视图想要调整自己的大小,它就会崩溃。原因是,当我增加容器的大小以匹配AU视图时,自动调整掩码约束指示AU视图再次增加其大小,从而导致无限循环。

到目前为止,最有效的方法是关闭AU视图的translatesAutoresizingMaskIntoConstraints,并通过监听帧更改通知来设置容器的大小。这似乎适用于所有的AUv2音频单元,但对于AUv3音频单元(特别是苹果的演示AUv3),我总是得到(1,1)的视图大小,这显然是无用的。我将非常感谢任何关于如何使其工作的见解……

EN

回答 1

Stack Overflow用户

发布于 2020-06-22 22:27:02

基于您提供的示例项目,这应该是可行的:

代码语言:javascript
复制
@interface MyViewController ()
{
    NSLayoutConstraint *widthConstraint, *heightConstraint;
}
@end

@implementation MyViewController


-(void)setFormatForBus:(AUAudioUnitBus*)bus
{
    AudioStreamBasicDescription fmt = {44100, kAudioFormatLinearPCM, kAudioFormatFlagIsNonInterleaved | kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked, 4, 1, 4, 2, 32, 0};  // Stereo audio on each bus
    AVAudioFormat* format = [[AVAudioFormat alloc] initWithStreamDescription:&fmt];
    NSError* error = nil;
    if (![bus setFormat:format error:&error]) {
        NSLog(@"Couldn't set the format for bus... %@", error);
        return;
    }
    
    bus.enabled = YES;
}

-(void)doLoad:(AVAudioUnit*)node controller:(NSViewController*)viewController
{
    NSView* auView = nil;
    if (viewController == nil) {
        auView = [[AUGenericView alloc] initWithAudioUnit:node.audioUnit displayFlags:(AUViewPropertiesDisplayFlag | AUViewParametersDisplayFlag)];
        auView.frame = self.view.frame;
        [self.view addSubview:auView];
    }
    else {
        self.auViewController = viewController;
        auView = self.auViewController.view;
        auView.translatesAutoresizingMaskIntoConstraints = NO;
        [self.view addSubview:auView];
    }

    NSSize size = _auViewController.view.frame.size;

    widthConstraint = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:size.width];
    heightConstraint = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:size.height];

    [self.view addConstraints:@[widthConstraint, heightConstraint]];

    NSLayoutConstraint* top = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:auView
                                                           attribute:NSLayoutAttributeTop multiplier:1.0 constant:0];
    NSLayoutConstraint* bottom = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:auView
                                                              attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0];
    NSLayoutConstraint* left = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:auView
                                                            attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0];
    NSLayoutConstraint* right = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:auView
                                                             attribute:NSLayoutAttributeRight multiplier:1.0 constant:0];

    [self.view addConstraints:@[top, bottom, left, right]];
}

- (void)viewDidLoad {
    [super viewDidLoad];

    NSArray* list = [[AVAudioUnitComponentManager sharedAudioUnitComponentManager] componentsPassingTest: ^BOOL(AVAudioUnitComponent *comp, BOOL *stop) {
        return [comp.typeName containsString:@"Effect"];
    }];
    
    AVAudioUnitComponent* component = nil;
    for (AVAudioUnitComponent* comp in list) {
        if ([comp.name containsString:@"MultibandCompressor"])  // That allows itself to be squashed. Also, it doesn't resize itself when "details" is toggled
//        if ([comp.name containsString:@"FilterDemo"]) // That one is squashed both vertically and horizontally... (Apple's sample AUv3 Audio Unit, needs to be installed first.)
//        if ([comp.name containsString:@"GraphicEQ"])  // That one is squashed vertically
//                    if ([comp.name containsString:@"AUDelay"])
            component = comp;
    }
    
    [AVAudioUnit instantiateWithComponentDescription:component.audioComponentDescription options:0
                                   completionHandler:^(__kindof AVAudioUnit *audioUnit, NSError *error) {
        if (error) {
            NSLog(@"Error instantiating AU: %@", error);
            return;
        }
        
        self.audioUnit = audioUnit;
        AUAudioUnitBusArray* inputBusses = audioUnit.AUAudioUnit.inputBusses;
        AUAudioUnitBusArray* outputBusses = audioUnit.AUAudioUnit.outputBusses;
        
        if (!inputBusses.count || !outputBusses.count) {
            NSLog(@"No busses...");
            return;
        }
        
        [self setFormatForBus:[inputBusses objectAtIndexedSubscript:0]];
        [self setFormatForBus:[outputBusses objectAtIndexedSubscript:0]];
        
        NSError* AUerror = nil;
        if (![audioUnit.AUAudioUnit allocateRenderResourcesAndReturnError:&AUerror]){
            NSLog(@"Error allocating resources: %@", AUerror);
            return;
        }
        [audioUnit.AUAudioUnit requestViewControllerWithCompletionHandler:^(NSViewController* viewController) {
            dispatch_async(dispatch_get_main_queue(), ^{
                [self doLoad:audioUnit controller:viewController];
            });
        }];
    }];
}

- (void)viewWillLayout
{
    [super viewWillLayout];
    if(_auViewController != nil) {
        [self.view removeConstraints:@[widthConstraint, heightConstraint]];
        NSSize size = _auViewController.view.frame.size;
        widthConstraint.constant = size.width;
        heightConstraint.constant = size.height;
        [self.view addConstraints:@[widthConstraint, heightConstraint]];
    }
}

@end
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62511212

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档