1

I want to make a backwards-compatible background view for my application (OS X 10.6+) and then use it inside my Application.xib.

I made a subclass of NSView which returns NSVisualEffectView or NSView (depends on macOS version).

BackgroundView.h

#import <Cocoa/Cocoa.h>

NS_ASSUME_NONNULL_BEGIN

@interface BackgroundView : NSView

@end

NS_ASSUME_NONNULL_END

BackgroundView.m

#import "BackgroundView.h"

@implementation BackgroundView

- (instancetype)init {
    if (@available(macOS 10.10, *)) {
        NSVisualEffectView *visualEffectView = [[NSVisualEffectView alloc] init];
        [self applyPropertiesForVisualEffectView: visualEffectView];
    }
    
    return [super init];
}

- (instancetype)initWithCoder:(NSCoder *)coder {
    if (@available(macOS 10.10, *)) {
        NSVisualEffectView *visualEffectView = [[NSVisualEffectView alloc] initWithCoder:coder];
        [self applyPropertiesForVisualEffectView: visualEffectView];
        
        // !!!"This coder requires that replaced objects be returned from initWithCoder:"!!!
        return (BackgroundView *)visualEffectView;
    }
    
    return [super initWithCoder:coder];
}

- (instancetype)initWithFrame:(NSRect)frameRect {
    if (@available(macOS 10.10, *)) {
        NSVisualEffectView *visualEffectView = [[NSVisualEffectView alloc] initWithFrame:frameRect];
        [self applyPropertiesForVisualEffectView: visualEffectView];
        
        return (BackgroundView *)visualEffectView;
    }
    
    return [super initWithFrame: frameRect];
}

- (void)applyPropertiesForVisualEffectView: (NSVisualEffectView *)visualEffectView API_AVAILABLE(macos(10.10)){
    [visualEffectView setState:NSVisualEffectStateActive];
    [visualEffectView setBlendingMode:NSVisualEffectBlendingModeBehindWindow];
}

@end

Then I inserted my BackgroundView class name as the class for the windows' main view. My XIB main view Custom Class

And then ticked off "Prefers coder at runtime": Ticked off option "Prefers coder at runtime"

But I'm getting this error for whatever reason. This coder requires that replaced objects be returned from initWithCoder:

How can I fix this issue?
I don't want to use some dynamic class injections like here because it looks like an awful solution in 2023.
I know I can add NSVisualEffect as a subview but I don't think it's as a good practice.

Thanks.

ReSophie
  • 121
  • 6

0 Answers0