Giter Site home page Giter Site logo

Comments (23)

sberrevoets avatar sberrevoets commented on May 13, 2024

Is this the latest version of the (unmodified) sample project? Did you install it using Cocoapods or directly from GitHub? That's a very strange issue...

from sdcalertview.

cojoj avatar cojoj commented on May 13, 2024

Yes, this is the latest version of unmodified sample project running on iOS 7.1 beta 2. I did download this from GitHub and called pod install in directory to install dependencies. So, IMHO it should be working...

from sdcalertview.

sberrevoets avatar sberrevoets commented on May 13, 2024

Yeah, should be okay. I haven't tested on iOS 7.1 yet, do you have the problem on iOS 7.0.4? The UIToolbar hack may be "fixed" in iOS 7.1, but I can't think of anything else.

from sdcalertview.

cojoj avatar cojoj commented on May 13, 2024

Unfortunately, I haven't tested on 7.0.4.

from sdcalertview.

sberrevoets avatar sberrevoets commented on May 13, 2024

I'm seeing the same on iOS 7.1. If you add a simple self.toolbar.translucent = NO; on line 302 of SDCAlertView.m it works, though it doesn't have the blur effect. I will leave the ticket open for now, but I won't actually do anything with it until iOS 7.1 gets closer to release. If Apple doesn't fix the behavior of the toolbar hack in the 7.1 GM when it's released, I'll look at a different way to implement the blur effect.

from sdcalertview.

cojoj avatar cojoj commented on May 13, 2024

Okey, that satisfies me for now!

from sdcalertview.

Clstroud avatar Clstroud commented on May 13, 2024

@scott90 Sorry for bumping this but 7.1 b4 still yields this issue and, what's worse, I've seen in a few places that Apple has made it current policy to reject new apps and updates that hijack the UIToolbar layer and attempt to use it elsewhere in their apps.

If I may recommend this library for implementing real-time blurring: https://github.com/radi/LiveFrost it is by far the fastest implementation I've seen and is straightforward to use.

Great work on SDCAlertView though, it has otherwise worked rather well for my purposes :-)

from sdcalertview.

sberrevoets avatar sberrevoets commented on May 13, 2024

@Clstroud I share your concerns, especially with Apple hammering down on using the hack. Though it appears that MDBlurView was (in)famous for its use of the toolbar hijack and only got denied because Apple got wind of that, they also seem to have done something in the 7.1 betas to make it stop working. And considering how far they are into the beta cycle, I don't think that change is going to be reverted either.

LiveFrost does appear to be a good alternative. I'm still trying to figure out queuing and the positioning issue with a keyboard. Both are pretty close to a solution (they sort of tie into each other), I just can't seem to find enough free time to finalize it.

I would say getting this blurring to work again has a higher priority than the other two open issues (which I've been working on and getting close to a final solution), so hopefully that's a quick fix as free time is very rare at the moment.

If you've used LiveFrost before and feel like trying to make SDCAlertView to work with it, you are more than welcome to. Please let me know in that case, then I won't put the effort into fixing that also.

from sdcalertview.

Clstroud avatar Clstroud commented on May 13, 2024

I only recently heard of LiveFrost and have thus only experimented with it a little, but as straightforward as it was to integrate with my other project, I don't see any reason why I couldn't fork and add it in. I'll make a note to try that tonight.

Since I'm not familiar with the internals of SDCAlertView, are there any design considerations I need to take into account or should I do a one-to-one rip out of the toolbar and replace with LiveFrost?

from sdcalertview.

sberrevoets avatar sberrevoets commented on May 13, 2024

Assuming there are no anomalies with LiveFrost, I believe simply replacing the toolbar with LiveFrost should do it. You may have to fiddle around with animations a bit in SDCAlertViewController. I had to manually animate the toolbar's layer, as simply animating its superview (SDCAlertView) didn't go over well. That can potentially be simplified then. Otherwise, I think the code is pretty straight-forward.

Thanks for your effort!

from sdcalertview.

garrettm avatar garrettm commented on May 13, 2024

I'm also dealing with this--do you guys have any updates? Should I start implementing LiveFrost or some other blurring technique myself?

from sdcalertview.

Clstroud avatar Clstroud commented on May 13, 2024

Whoops, had a class start right about the time I got @scott90's message and forgot to reply!

I have a reminder on my desk staring me in the face, but there's one other requirement in my "queue" I have to finish before I can pivot over and take care of this. That other thing had some wonderfully interesting issues pop up, which is why I didn't get to this as immediately as I had hoped.

That said, @garrettm if you have the time on your hands and would like to fork an implementation of LiveFrost, I don't see why you couldn't do that. Otherwise I'll be on it just as quick as I can :)

from sdcalertview.

sberrevoets avatar sberrevoets commented on May 13, 2024

I finally was able to fix the alert queuing tonight, so make sure you pull the latest changes to avoid merge conflicts.

from sdcalertview.

sberrevoets avatar sberrevoets commented on May 13, 2024

I decided to fix it differently. I tried implementing LiveFrost and FXBlurView, but I didn't like the results. Maybe I didn't mess with the settings enough, but I didn't like where it was going. I had blurs with weird radii, tintColors or workarounds to make sure the previous window's view was being blurred.

That's why I decided to simply insert the entire toolbar as a subview of SDCAlertView, not just its layer. I've tested this on iOS 7.1 beta 4, and it works. I also believe that Apple will not have anything against this. MDBlurView was rejected because it messed with internal view/layer hierarchies, which this solution doesn't.

If you are not comfortable using this solution, feel free to implement LiveFrost or FXBlurView. A pull request is always welcome as well, but I am pretty picky when it comes to making sure it looks the same as UIAlertView, so I can't make any guarantees that it will be merged into master. Having a different implementation as a backup in case Apple decides that this solution is also unacceptable (which I deem very unlikely, because it's really hard to tell legitimate from illegitimate uses) is probably a good idea.

Comments and suggestions are welcome as always.

from sdcalertview.

Clstroud avatar Clstroud commented on May 13, 2024

Oh no, I just logged into GitHub to tell you that I had a few spare hours this evening and integrated it. Yay, open source! Oi. Github needs a semaphore analog for these kinds of things ;-)

I obviously ran into the same issues, but I jumped the gun and integrated a version of what's been discussed over here into LiveFrost itself. The result as of now is thus:

Screenshot

I have a fix for the overly bright coloration, don't worry about that, but do you have any notion for what the desired blur radius might be? I'll play with it and see, but I actually think they may simply blur the shadow overlay and make the alert itself ever so vaguely transparent:

Screenshot

There is definitely a blur applied, but the image behind the alert has a crisp line, indicating that they are probably doing a cheap trick. Thoughts?

And regarding the UIToolbar "hack," I haven't shipped my app yet and won't be for a while, but I wouldn't be comfortable with that if it is at all avoidable. At the very least, it's a distinct violation of the HIG and I'm not sure it's the most responsible way to treat others' codebases. Alas, that's your call to make :-)

from sdcalertview.

sberrevoets avatar sberrevoets commented on May 13, 2024

@Clstroud Of course that would happen :-), but it doesn't sound like your work was for nothing.

Like you, I didn't know what blur radius to use either. FXBlurView has a default of 40 points, which the creator claims to be "similar to the iOS 7 blur effect". I don't know if that's true, I didn't get that far, but I don't like using 40 simply because it looks like it. Without exception, all constants in this project are based on values reverse-engineered from UIAlertView. If you somehow can get deeper into the APIs that provide the blurring and can somehow get the actual value from iOS, I'm all for that.

I'm not sure what you mean by "the image behind the alert has a crisp line". If you mean that the image isn't blurred outside of the alert: you're right. The alert really only blurs stuff directly behind it, so you can't simply apply a blur to the entire underlying view.

You're right in that this hack technically violates the HIG. However, this toolbar doesn't even look like a toolbar. It's not like we show a toolbar with a bunch of buttons in the middle of the screen. Apps are not usually rejected for not following the HIG, it has to be a really bad violation to not make it into the App Store.

That's not to say that I like this solution. It is, after all, a hack and I prefer not to use any. That's why I said that if we can achieve the same results with a more acceptable alternative, I'll gladly use that. Just keep in mind: I don't want to apply a blur effect. I want to apply the same blur effect.

from sdcalertview.

Clstroud avatar Clstroud commented on May 13, 2024

@scott90 To clarify, I'm saying to look at the background of the empty, system-derived alert above; it has a crisp silhouette of the image I stuck in the table cell. That would seem to indicate that there is, in fact, no blur applied. dylib-injecting some quick runtime introspection code confirms that, at least for your demo project alerts, there is no blurring taking place. The relevant ivars are nil pointers. Whether that remains the case for the sibling SpringBoard alert classes I can't say. They're irrelevant to this project so I didn't check, but I'm almost certain they blur… However, I am reasonably confident that they simply aren't blurring the application-bound alerts for performance reasons disused below. Do you have any in-app examples that demonstrate otherwise? I really hope not… we have essentially zero chance of identifying their strategy for discerning when to blur and when not to.

From things I've heard from certain folks whom I would never question on the matter, the reason messing with the UIToolbar layer is frowned upon, why we don't have a generic API for blurring, and why that layer will occasionally behave erratically when used in certain circumstances, is because it requires optimizations that demand the underlying layer hierarchy be "just so." The restrictions are merely them trying to prevent those edge cases because they simply didn't have enough time to refine it into something more generalized that performed well enough prior to iOS 7's launch. This is why I'm actually against the use of that technique, not so much because of the HIG.

You're correct — by and large, no one even reads that thing. However I don't see your "new" usage pulling any wool over their eyes.… There isn't a single public way to replicate their technique 100% since it's (from what I understand) very hardware optimized. If they see the effect, it's very easy for them to introspect the hierarchy. Will they? Depends on how against its improper use they are, but given the breadth of their static analysis and various other tools, that's not a crusade I would want to risk starting. You've got ~450 stars on this repo — I think it is safe to say that you have a ton of users and it could easily be flagged. Not to mention that UIAlertView can't have its view hierarchy modified, so they may take a peek behind the curtain simply because you've otherwise got an identical implementation, which looks suspect. Enough of that though, lets just figure out what they do and refine SDCAlertView to replicate it. Then there's nothing to fuss over :-)

When you say you "reverse engineered" the UIAlertView class, what exactly do you mean? I dumped the background image from memory and it matched yours identically so I'm not sure whether you did a similar trick or if you yanked that resource from the UIKit resource cache. I don't want to take redundant steps. One thing I haven't quite ascertained yet is the blasted background color for the alert. Perhaps it's simply white with the radial gradient background image overlay, but I'm not convinced that's all there is to it. I did an image diff and the background colors of the alerts were not identical. The button text colors/fonts also seemed slightly off when comparing side by side… but that's less of an issue for now. I'll try to remember to run an image diff on those as well. If I get some more time I may traverse the layer tree and render their contents to disk to make sure there isn't another asset being loaded for that and stuck inside the layer itself… but meh. It will have to wait until after my exam Tuesday morning.

from sdcalertview.

sberrevoets avatar sberrevoets commented on May 13, 2024

To clarify, I'm saying to look at the background of the empty, system-derived alert above; it has a crisp silhouette of the image I stuck in the table cell. That would seem to indicate that there is, in fact, no blur applied. dylib-injecting some quick runtime introspection code confirms that, at least for your demo project alerts, there is no blurring taking place. The relevant ivars are nil pointers.

I'm still not sure we're on the same page here. Are you talking about, in the second image you posted, the small portion of the image that shows to the left of the alert? Because that part isn't supposed to be blurred.

Whether that remains the case for the sibling SpringBoard alert classes I can't say. They're irrelevant to this project so I didn't check, but I'm almost certain they blur… However, I am reasonably confident that they simply aren't blurring the application-bound alerts for performance reasons disused below. Do you have any in-app examples that demonstrate otherwise? I really hope not… we have essentially zero chance of identifying their strategy for discerning when to blur and when not to.

It is an assumption on my part. When I started the project, I didn't realize the system distinguished between SpringBoard alerts and "app context" alerts. I created an app alert, and mimicked its view hierarchy as much as possible. I noticed the _UIBackdropView class in the hierarchy, and assumed that's how they get the blur. I didn't really look much further than that, because, well, the class is private and (especially at the time, when iOS 7 was just released) there weren't many blurring options available.

Looking at _UIBackdropView a little closer, there's some interesting stuff going on. Removing it altogether results in the same, backgroundless alert that started this whole issue. It has some easy to read properties (_blurRadius = 0, _backdropVisible = YES) and in this objc.io article, they mention that _UIBackdropView is used as a background for UIToolbar.

From things I've heard from certain folks whom I would never question on the matter, the reason messing with the UIToolbar layer is frowned upon, why we don't have a generic API for blurring, and why that layer will occasionally behave erratically when used in certain circumstances, is because it requires optimizations that demand the underlying layer hierarchy be "just so." The restrictions are merely them trying to prevent those edge cases because they simply didn't have enough time to refine it into something more generalized that performed well enough prior to iOS 7's launch. This is why I'm actually against the use of that technique, not so much because of the HIG.

Can't agree more, but my experience with Core Graphics was (and is) not nearly sufficient to write a blurring technique that would work for this project. But I needed something and the toolbar was easy to use and has the same result.

You're correct — by and large, no one even reads that thing. However I don't see your "new" usage pulling any wool over their eyes.… There isn't a single public way to replicate their technique 100% since it's (from what I understand) very hardware optimized. If they see the effect, it's very easy for them to introspect the hierarchy. Will they? Depends on how against its improper use they are, but given the breadth of their static analysis and various other tools, that's not a crusade I would want to risk starting. You've got ~450 stars on this repo — I think it is safe to say that you have a ton of users and it could easily be flagged. Not to mention that UIAlertView can't have its view hierarchy modified, so they may take a peek behind the curtain simply because you've otherwise got an identical implementation, which looks suspect. Enough of that though, lets just figure out what they do and refine SDCAlertView to replicate it. Then there's nothing to fuss over :-)

I honestly don't see them do that. I can't find any sources, but a while back it was reported that the average time they actually have the app open, is only a few seconds. They do their static analysis, check for private uses, make sure it doesn't crash immediately, and be done with it. At the same time, they did make a point of explicitly saying MDBlurView is not acceptable, so maybe I'm underestimating their review.

When you say you "reverse engineered" the UIAlertView class, what exactly do you mean? I dumped the background image from memory and it matched yours identically so I'm not sure whether you did a similar trick or if you yanked that resource from the UIKit resource cache. I don't want to take redundant steps. One thing I haven't quite ascertained yet is the blasted background color for the alert. Perhaps it's simply white with the radial gradient background image overlay, but I'm not convinced that's all there is to it. I did an image diff and the background colors of the alerts were not identical. The button text colors/fonts also seemed slightly off when comparing side by side… but that's less of an issue for now. I'll try to remember to run an image diff on those as well. If I get some more time I may traverse the layer tree and render their contents to disk to make sure there isn't another asset being loaded for that and stuck inside the layer itself… but meh. It will have to wait until after my exam Tuesday morning.

I manually inspected the view hierarchy (in retrospect, coughing up the money for Reveal would have been worth it, but I hadn't heard of it yet...) and copied values directly. Frames were translated to constraints, but padding values, button colors, separator colors, the dimmed background color, parallax magnitudes, animation parameters, etc. were all directly taken from a "real" alert (the app kind, not SpringBoard). I obtained the radial background through Quicklook in the debugger when inspecting the image view for it.

I didn't go as deep as inspecting the layer tree, but since UIView's values are derived from the top-level layer, those should match. In any case, I will dive deeper into _UIBackdropView, and maybe we can figure out how we can configure one of the other blurring techniques so that it looks very much like the app alerts.

from sdcalertview.

Clstroud avatar Clstroud commented on May 13, 2024

I think I'm just seeing something you aren't… possibly because one of my monitors is an older matte ACD, which tends to show these kinds of things a little better. See if this helps make what I'm saying clear:

transparency_demo

The image is my profile picture because it's the smallest and squarest thing I had in reach at the time… You can see quite clearly that there is no blur applied at all. At least, not in that case. See what I'm saying now?

Reveal isn't of much assistance here. I tried it just for fun, but it's only designed to handle the app's contents, not the contents of other UIWindows.

If you really want to know how it's built, you need to study the class dumps carefully. There are a bunch of private classes at the bottom ('_' prefixed) that I started injecting dylibs into last night but a lot of it just isn't being used in the app alerts. It's kind of a bummer, actually. Not to mention the apparent amount of legacy code in there. Lots of cruft that never gets called — at least not under typical circumstances.

EDIT: I also meant to note that _UIBackdropView looks like a pretty intricate class-cluster (at first glance, mind you) and that there aren't separate classes for each "type" of UIAlertView, however the ivar map inside the class seems to suggest very clear distinctions between each context that the alert may be presented in.

EDIT EDIT: I can't pass up a perfectly good reason to procrastinate on exam studies… so here's this: http://cl.ly/3i1l3j0M0N1H Slowed all system animations to a crawl as you seem to have wanted to do on Twitter. Helped answer my question as to whether blurring was happening at all. Spoilers: it isn't.

from sdcalertview.

sberrevoets avatar sberrevoets commented on May 13, 2024

Ah, yes, I see it now. I didn't see it on either of the two monitors I work on frequently, but the second image is pretty clear. Yeah, this isn't blurred at all.

I did study the class dumps and went through everything in the debugger. Just traversing view hierarchy and printing relevant values. Took a while, but worked eventually. Going through the mess that is UIAlertView (even the public header) made me realize how much of a rush iOS 7 really was. Definitely a lot of seemingly unnecessary stuff in there.

Watch out with the class dumps you posted, by the way. They are old (early July) and likely outdated, which may be why you don't see certain methods called. I ran into the same issue when writing the coordinator. I was very surprised why certain methods weren't called, but then I looked at the class dumps by nst, which he uploaded after the iOS 7 was released. Now a lot more methods were called and it was pretty easy to figure out how to write SDCAlertViewCoordinator.

Anyway, to get back to the point: looks like you were right and there is no blurring taking place. At the same time, _UIBackdropView provides some background. It's translucent for sure, but I'm not sure what kind of magic is exactly going on then.

PS: A lot of people got involved in that on Twitter, but in case you're interested: eventually someone came up with this trick, which worked well.

from sdcalertview.

Clstroud avatar Clstroud commented on May 13, 2024

Ah, yes, I see it now. I didn't see it on either of the two monitors I work on frequently, but the second image is pretty clear. Yeah, this isn't blurred at all.

Glad that got the point across :-)

I did study the class dumps and went through everything in the debugger. Just traversing view hierarchy and printing relevant values. Took a while, but worked eventually. Going through the mess that is UIAlertView (even the public header) made me realize how much of a rush iOS 7 really was. Definitely a lot of seemingly unnecessary stuff in there.

Good deal. The way you phrased it made it sound like you were digging around blindly so I wanted to make sure you knew that invaluable resource existed.

Watch out with the class dumps you posted, by the way. They are old (early July) and likely outdated, which may be why you don't see certain methods called. I ran into the same issue when writing the coordinator. I was very surprised why certain methods weren't called, but then I looked at the class dumps by nst, which he uploaded after the iOS 7 was released. Now a lot more methods were called and it was pretty easy to figure out how to write SDCAlertViewCoordinator.

Thanks, and good call there. It would probably be best to go ahead and dump the 7.1 headers just to be sure that nothing has changed. As much UI as they've altered, I wouldn't be surprised if they cleaned house with the alert stack. On the other hand, they seem perfectly willing to just leave tons of cruft littered around so perhaps it's just as bad or even worse!

The weird thing is that Substrate wasn't griping about those symbols not existing when it was doing its swizzle, so I'm not sure what to make of that. Surely they don't just keep all versions of their methods in place?

Anyway, to get back to the point: looks like you were right and there is no blurring taking place. At the same time, _UIBackdropView provides some background. It's translucent for sure, but I'm not sure what kind of magic is exactly going on then.

The odd thing is that their header for UIAlertView doesn't have an '@Class' declaration for _UIBackdropView, or any subclasses thereof. Are you absolutely certain it's being used by UIAlertView? I mean, obviously UIToolbar and co. need it for their blurs, but I am not seeing much evidence that UIAlertView even imports it. Any info there? Perhaps I grossly overlooked something…

PS: A lot of people got involved in that on Twitter, but in case you're interested: eventually someone came up with this trick, which worked well.

So you were able to get into that window and slow it down? My impression was that you didn't have luck with it. Oh well, it was easy to do and a fun exercise.

from sdcalertview.

sberrevoets avatar sberrevoets commented on May 13, 2024

Good deal. The way you phrased it made it sound like you were digging around blindly so I wanted to make sure you knew that invaluable resource existed.

Haha no, no way I could have pulled this off just doing things blindly. I had a method set up with local variables that captured all individual views in the hierarchy so I could inspect them. In the future, I might create a Debug category on UIAlertView or something that makes all of this a little easier.

Thanks, and good call there. It would probably be best to go ahead and dump the 7.1 headers just to be sure that nothing has changed. As much UI as they've altered, I wouldn't be surprised if they cleaned house with the alert stack. On the other hand, they seem perfectly willing to just leave tons of cruft littered around so perhaps it's just as bad or even worse!

That may be a good idea, though I obviously want to keep it backwards compatible. The method names may be informative enough to understand what's going though, so that may be worth a shot.

The weird thing is that Substrate wasn't griping about those symbols not existing when it was doing its swizzle, so I'm not sure what to make of that. Surely they don't just keep all versions of their methods in place?

No idea. Maybe the methods you were looking at hadn't changed, but there surely were some changes in _UIModalItemsCoordinator. I don't think I noticed any changes in UIAlertView itself actually. This only came up recently when I decided that a coordinator class was appropriate.

The odd thing is that their header for UIAlertView doesn't have an '@Class' declaration for _UIBackdropView, or any subclasses thereof. Are you absolutely certain it's being used by UIAlertView? I mean, obviously UIToolbar and co. need it for their blurs, but I am not seeing much evidence that UIAlertView even imports it. Any info there? Perhaps I grossly overlooked something…

The name of the class may indicate otherwise (probably for backwards compatibility), but UIAlertView is a model class. It never makes it into the view hierarchy. The alert calls out to the coordinator, who calls out to _UIModalItemsPresentingViewController, which initializes a _UIModalItemRepresentationView. This view has a _UIModalItemAlertContentView subview for displaying the alert's contents, and a _UIModalItemAlertBackgroundView.h for the background. And sure enough, _UIModalItemAlertBackgroundView.h does have a forward declaration (and instance variable) to _UIBackdropView.

It also has a _fillingView property which, I assume though haven't confirmed, is the radial image. The method _gradientImageForBoundsSize:withInnerColor:outerColor: is a little disconcerting, as SDCAlertView just uses one image, regardless of the alert's size...

Anyway, that (and by inspecting the view hierarchy) is how I know it uses _UIBackdropView, and why I assumed its purpose is to apply a blur. Turns out it doesn't actually blur, but it still provides a background that I haven't been able to reproduce yet. If you want to take a crack at it, feel free.

EDIT: Since this issue is technically solved, I've created a new issue where we can continue this discussion.

from sdcalertview.

sberrevoets avatar sberrevoets commented on May 13, 2024

Since this issue is technically solved, I've created a new issue where we can continue this discussion.

from sdcalertview.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.