1

I am looking to build a custom error message in the form of a UIView. I would like to use this UIView for each UIViewController within my app. Obviously I don't want to recreate it for each screen, so I am looking for the best solution to "share" it.

Would it be better to create it as a UIViewController and add it that way or is there a better approach?

4
  • Yes, you can create as shared/single instance of your custom view using singletone method, and can use this in all the UIViewController Commented Aug 3, 2018 at 9:35
  • 2
    @vivekDas that is a terrible advice from app architecture's point of view, not to mention error-prone and violating just about every UI design principle Commented Aug 3, 2018 at 9:43
  • How can you say its terrible, it depends on the usage if you can't use it its your problem , there is no such restriction @mag_zbc Commented Aug 3, 2018 at 9:56
  • Based on the comments below I've gone down the UIViewController route, I open it up as a popover via a segue and just pass through the error message. Thanks all Commented Aug 3, 2018 at 12:01

4 Answers 4

3

UIView instances are meant to be used in only one place. They can only have one superview and thus cannot be used in several view hierarchies at the same time.

If you change the superview of a view, you will actually move the view.

There are two possibilities I think:

  • either you want to always have this error message on screen. In that case, you should probably create a dedicated UIViewController as you mentioned, and always display it on screen,
  • or you want to display different errors. In that way, it makes sense to create an instance of your UIView for every controller in which you display an error.
Sign up to request clarification or add additional context in comments.

Comments

1

Yes, use a ViewController, it is better than a simple view. Your message could have actions like buttons.

To avoid too many code duplications, you may use a mixin :

protocol ErrorDisplay {
    func display(_ error: Error)
}

extension ErrorDisplay where Self: UIViewController {
    func display(_ error: Error) {
        let viewController = ErrorViewController(error: error)
        // You could also add it as a child view controller rather than presenting it, 
        // if you want to add its view in the current hierarchy
        present(viewController, animated: true, completion: nil)
    }
}

And implement the protocol in each view controller that wishes to display a error.

extension LoginViewController : ErrorDisplay {}
extension SettingsViewController : ErrorDisplay {}
...

Comments

1

If you want a view which is always present on screen at that time you can use window to display a view.

Window is Root of all view that displaying on screen, Window always present so once you add your view in window that will always be present in screen.

Just use below code to add view to window

let window = UIApplication.shared.keyWindow!
let v = UIView(frame: CGRect(x: window.frame.origin.x, y: window.frame.origin.y, width: window.frame.width, height: window.frame.height))
window.addSubview(v);

Comments

0

For this problem, I prefer you to create a UIView class and you can reuse it in your viewController. For doing this follow these steps,

1. Create a Xib of UIView and design it what ever you want.
2. Create a UIView class
3. Change the fileOwner of Your UIView XIB to the created UIView class
4.  Create an Outlet of ContentView in YourView.h
 @property (strong, nonatomic) IBOutlet UIView *contentView;
5. Add the following codes in YouView.m

 -(instancetype)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if(self)
    {
        [self customInit];
    }
    return self;
}

-(instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if(self)
    {
        [self customInit];
    }
    return  self;
}

-(void) customInit
{
    [[NSBundle mainBundle]loadNibNamed:@"View" owner:self options:nil];
    [self addSubview:self.contentView];
    self.contentView.frame = self.bounds;
}

6. Use this UIView in your ViewController what ever you want.

YourView *YourViewObj = [[YourView alloc] initWithFrame:CGRectMake(0, 0, 100,100)];
[self.view addSubview:YourViewObj];

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.