Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exclude some views or views' hierarchy from being render by NUI #65

Merged
merged 2 commits into from
Aug 7, 2013

Conversation

huguesbr
Copy link
Contributor

Context

Ideally NUI CSS Parse will have a better CSS Selector support but until then it's pretty hard to exclude some views from being render.
You can of course set nuiClass = @"none" but what about view (or subviews) for which you don't have a direct access to (ABPeoplePickerNavigationController, ...).
In my case, if I use one of the default theme and display a person picker, I can't see contacts name.

Proposed Solution

I've added two new css property (exclude-views and exclude-subviews) which allow to specify some view's class (or view's class subviews) that should never be render by NUI.
I've also added another gloabalExclusions property on NUISettings which will exclude views or subviews of specified class to be render.

Usage

  • New CSS Property

NUIStyle.css

...
Button {
    background-color: #FFFFFF;
    border-color: @primaryBorderColor;
    border-width: @primaryBorderWidth;
    font-color: @primaryFontColor;
    font-color-highlighted: @secondaryFontColor;
    font-name: @secondaryFontName;
    font-size: 18;
    height: 37;
    corner-radius: 7;
    exclude-views: UIAlertButton;
    exclude-subviews: UITableViewCell,TDBadgedCell,UITextField;
}
...
  • New Global Exclusions
int main(int argc, char *argv[])
{
    @autoreleasepool {
#if kNUIEnabled
        [NUISettings initWithStylesheet:@"NUIStyle-1debit"];
        [NUISettings setGlobalExclusions:@[@"ABMemberCell", @"ABMultiCell"]];
#endif
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([HBRAppDelegate class]));
    }
}

Alternative solution

It also possible to only use nuiClass and having a new class call @"noneAll", and do a test on it in applyNui.

- (void)applyNUI
{
    // Styling shouldn't be applied to inherited classes
    if ([self class] == [UIView class]) {
        [self initNUI];
        if (![self.nuiClass isEqualToString:@"none"]) {
            BOOL isIncludedInNoneAllView;
            UIView *superview = self;
            while(superview != nil){
                if([superview.nuiClass isEqualToString:@"NoneAll"]){
                    self.nuiClass = @"none";
                }
                superview = superview.superview;
            }

            if (![self.nuiClass isEqualToString:@"none"]) {
                if ([self class] == [UIView class] &&
                    [[self superview] class] != [UINavigationBar class]) {
                    [NUIRenderer renderView:self withClass:self.nuiClass];
                }
            }

        }
    }
    self.nuiIsApplied = [NSNumber numberWithBool:YES];
}

It will give less flexibility, be a bit more consuming (will escalate view hierarchy each first time nui is apply to any class).
If you like this solution better, let me know I will submit another pull request.

…c class from rendering (useful to disable NUI in UIActionSheet, UIAlertView, ...)
… will be exclude from any NUI customization (equivalent of setting exclude-views and exclude-subviews for all NUI styles);
@tombenner
Copy link
Owner

Nice! Thanks for this. This is indeed something that needs to be addressed soon. I'm a little hesitant to put in a stopgap, but given how important it is, this may make sense. I agree that your initial solution is preferable to the @"NoneAll" route. I'm going to quickly think over if there are any other ways to quickly resolve this, but will either merge this or have a new solution ready before Tuesday.

If anyone else has other thoughts about this, definitely feel free to chime in!

@huguesbr
Copy link
Contributor Author

Hey Tom,
Thank for the feedback, I will also try to think of another solution too, I not a big fan of this one, it look a big hacky..
Also some UI elements are not subclass of UIView so they might be ignored by the current solution, I haven't put this logic on all NUI elements.

@tombenner
Copy link
Owner

Sure thing--thanks again for doing this. That's a good point about elements that don't inherit from UIView; some of those are the ones where this issue is the most problematic, at least in my experience.

It may not be an enormous amount of work to set up descendant selectors (#60), which would be a good long-term solution; I just haven't had time to take a good look at doing it yet, but may have time in the next few days.

@tombenner
Copy link
Owner

Very sorry for the delay on this; things've been hectic lately. I'd like to think a little more about other possible routes before using this just yet, especially since we both feel that there might be a more durable way to resolve it.

If anyone else has thoughts on solutions, definitely feel free to chime in, too.

@1debit
Copy link

1debit commented Feb 1, 2013

No problem, I agree that it's more a hack than a real fix..

@tilowestermann
Copy link

Is there already a fix in sight? I'd like to use NUI, but I'm using some third party controls that just don't look what they should look like after applying the NUI stylesheet. I'd like to set nuiClass to none for the top element (e.g. ABCalendarPicker) so that the child views do not get styled at all.

@huguesbr
Copy link
Contributor Author

huguesbr commented Apr 4, 2013

@tilowestermann you can use my fork, but I haven't maintain it at all.. it basically allow to do what you need.

@tombenner
Copy link
Owner

Sorry for the delay on this; been meaning to develop a solid solution for it, as it definitely needs to be addressed. In the short term, something like @huguesbr's +[NUISettings setGlobalExclusions:] (see the opening comment in this thread) seems like it might make the most sense. I'm a little wary of traversing the ancestors of every UIView, but it might be necessary.

Any thoughts on what approach you all would prefer?

@wm-j-ray
Copy link

I would like to be able to exclude specific third party classes by name if possible.

@schiffy91
Copy link

The good news is that @huguesbr's fork can still be merged with master without conflicts. The bad news is that, without the PR being accepted, @huguesbr's fork is not a viable long-term solution, as things will inevitably change. @tombenner, is there a specific way you'd like this to be implemented? I can dig around this weekend and get to work on an elegant solution.

@tombenner
Copy link
Owner

@aschiffhauer, thanks for following up on this. I had been hoping that I (or someone else) would think of an elegant solution for this, but I haven't yet. Traversing the ancestors of every UIView feels excessive, but I haven't actually done any benchmarking of it; it may turn out to be a trivial performance change and thus a good solution. If anyone would like to do that benchmarking to prove its viability, that'd be fantastic.

Otherwise, if you'd like to dig around for other possible solutions, definitely go for it!

@schiffy91
Copy link

@tombenner, #145 provides an alternative solution to excluding classes, and their derivatives, from NUI's styling. In addition, the PR addresses -568h@2x images and cleans up the demo project.

tombenner added a commit that referenced this pull request Aug 7, 2013
Exclude some views or views' hierarchy from being render by NUI
@tombenner tombenner merged commit 7c498a7 into tombenner:master Aug 7, 2013
@tombenner
Copy link
Owner

Finally had a chance to do some light benchmarking for this, and the results look reasonable. There's obviously a great need for something like this, and this is a simple, reasonably performant solution that's opt-in (i.e. a user won't see any significant performance changes unless they explicitly use exclusions), so I think it makes sense to adopt it. The API for it is simple enough that we could always rewrite the underlying code if need be, too.

Defining exclusions using stylesheet properties isn't ideal from an academic standpoint, but I prefer it to forcing the user to use yet another configuration pattern in Obj-C. Our parser isn't ready for anything more robust than this.

I've merged and closed this, but if anyone has thoughts on how to further improve it, feel free to chime in. @huguesbr, many thanks for this, and sorry for my delay in seriously evaluating it. I'll add documentation for it shortly.

@huguesbr
Copy link
Contributor Author

huguesbr commented Aug 7, 2013

Hey @tombenner , no pb, I'm glad that my work was useful and that you've accepted it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants