iKy1e | iOS Developer

Jared Sinclair: Untouchable

jaredsinclair:

I dislike iOS 7 so strongly that I feel inclined to begin this post with a disclaimer about how much I admire Apple. Apple is my hero. They’ve always inspired me to be better at what I do, even when I was an ICU nurse. But they are not perfect. I can and should criticize their worst work when I…

This describes quite nicely some of the issues I have with iOS 7’s design principles.

Via Jared Sinclair

When the live demo works during a talk

securityreactions:

image

by @f1nux

Same applies for a successful landing on Kerbal, or landing a 180 wall flip!

Via Infosec Reactions

How to put UISlider’s in UIScrollView’s

It’s a fairly simple request you’d imagine. Simply put a slider inside some content which scrolls.

As this is on iOS that content is obviously inside a UIScrollView.

 

The Problem

The main problem with the above is that they don’t like each other. If you place a standard UISlider inside a normal UIScrollView the scroll view delays the touches for a fraction of a second to see if you are scrolling. Here is the big problem, you swipe sideways to scroll and you, want to, swipe sideways on the sliders thumb to quickly change it’s value.

As a result you have to tap, pause and then drag the slider in order to use it. Manageable but hardly smooth or ideal to use.

Of course there is a very simple way to avoid this.

scrollView.delaysContentTouches = NO;

Simple? Well, at least for me on iOS 5, a little too simple. This caused almost all objects to prevent my scrollView from scrolling, buttons, sliders, even an image view seemed to block it. So we filter for the slider?

If we look at the UIScrollView documentation we see a few little things that allow us to control the delays and cancelling touches. Creating a custom subclass gives us a little more power, but still not enough.

What do we do with our new subclass then? Well, we need to control when to allow touches to behave normally and when we should scroll.

@interface KHCustomScrollView : UIScrollView
@property (nonatomic, assign) BOOL ignoreSliders;
@end


@implementation KHCustomScrollView
@synthesize ignoreSliders = _ignoreSliders;

-(BOOL)touchesShouldCancelInContentView:(UIView *)view{
    if (self.ignoreSliders) {
		if ([view isKindOfClass:[UISlider class]]) {
			return NO;
		}
		else {
			return YES;
		}
	}
	
	return [super touchesShouldCancelInContentView:view];
}
@end


// Somewhere else...
scrollView.canCancelContentTouches = YES;
scrollView.delaysContentTouches = NO;
scrollView.ignoreSliders = YES;

What we do here is tell it we want the scrollView to let all touches to start normally, but we want it to be able to cancel them if it wants to scroll. Instead of the normal behavour of delaying them until its decided whether or not to scroll it now cancels touches when it wants to. Then we have our scrollView say it can cancel touches and start scrolling for everything, other than sliders.

Now can you guess the problem here?

If we touch anywhere on the slider it will not scroll, however the slider only responds over the thumb image that indicates the value selected. But we can fix this too, however we have to work with the sliders themselves :(, although luckily we don’t need to subclass them.

// Somewhere...

-(void)monitorSlider:(UISlider*)slider{
    [slider addTarget:self action:@selector(willSlide:) forControlEvents:UIControlEventTouchDown];
	[slider addTarget:self action:@selector(didSlide:) forControlEvents:UIControlEventTouchUpInside];
	[slider addTarget:self action:@selector(didSlide:) forControlEvents:UIControlEventTouchUpOutside];
	[slider addTarget:self action:@selector(didSlide:) forControlEvents:UIControlEventTouchCancel];
}
-(void)willSlide:(id)sender{
	scrollView.scrollEnabled = NO;
}
-(void)didSlide:(id)sender{
	scrollView.scrollEnabled = YES;
}


// Someone else...
[self monitorSlider:slider];



// In our scrollView subclass we made earilier
if ([view isKindOfClass:[UISlider class]] && !self.scrollEnabled) {
    return NO;
}

By the way that `scrollView.scrollEnabled` is only state storage. It could have been written scrollView.tag = 42, if (scrollView.tag == 42) …

So now we allow touches to reach things inside the scrollView, we know when the slider was touched on its thumb image, and we can control which touches are canceled and which are allowed to prevent us from scrolling.

 

 

And finially, here’s an example project on Github to show you an example for each stage of this article. Hope someone finds this useful as I couldn’t find anything on the subject.


The state of toggles on iOS

Toggling things like wifi or bluetooth on and off quickly and conveniently is a feature that has been added to lots of apps and tweaks since very early on since iOS was first jailbroken.

In the past

This trend started off with things like Bossprefs which managed various settings on the device but was a stand alone app and didn’t have much flexibility:

Bossprefs screenshot

Then you have SBSettings. SBSettings got lots of attention and quickly became one of the default things people installed on their jailbroken devices once they finished jailbreaking. And of cause it has it’s own API so other developers could have it control their things, such as SSH or UserAgentFaker.

SBSettings screenshot

The problem with SBSettings API is it was designed quite early in iOS’s history and so isn’t designed very natively and could be much better (more on that later). It has it’s advantages though, isn’t quite simple. Each toggle has a dylib with a few simple C functions. SBSettings opens them and calls the functions to make things happen or check it’s state. It also includes some more advanced options like presenting extra windows to show things like a list of processes running or a slider for the brightness. As a sign of it’s age it must respring to reload it’s settings. When it was designed that was the norm and having a tweak which could adapt to settings on the fly without resrpinging would be a killer feature.

Now

iOS and ObjectiveC has moved on quite a bit now and is much more advanced and more refined then it was. SBSettings was good but after iOS 4 I stopped using it. This was mostly down to notification centre taking over as the “above” window on my device. Having 2 windows that drop down form the top of the screen as a control centre for my device each activated under different circumstances just feels wrong, so I don’t us it anymore (and it although quite a few people still use it, it isn’t as popular as it once was).

NCSettings has mostly replaced it for me. SBSettings has a mode to run inside notification centre but it just doesn’t fit well. It has been adapted quite well, but it and it’s toggles weren’t designed for that purpose. NCSettings by comparison was designed from the start to run in the notification centre and fits in very well with a minimal stripped back design.

NCSettings screenshot

And now everything offers some basic controls and toggles. Deck is an example of something like NCSettings designed to do just that. However, lots of tweaks now offer some sort of toggles, Auxo for example extends the simple mute/orientation lock toggle in the switcher to a more general control of the devices basic features. The problem with all these things is they are limited to what you can convince the developer to add support for and anything like SSH or your own add-on which is a separate package and my not be installed on everyones devices is going to be a hard sale to get added. In short none of them have an API and there’s defiantly not a unified API among them. The closest I’ve seen is a tweak using SBSettings API for itself.


Now that I’ve briefly outlined how toggles on iOS currently are I’m going to outline how I think they should, or rather could, be in another blog post.


Stream of Superior Consciousness: The Apple Haters' 7 Stages of Grief

farley:

I wish I could take credit for this but I can’t. Got this from an arstechnica.com forum posting from way back in June of 2010.

The forum poster’s moniker is The Real Blastdoor. Please join me in thanking him for this, because it is absolutely pure gold. Additionally, each and every word is true.


The Apple haters’ stages of grief go something like this:

  1. Predict failure of new Apple product
  2. Attribute early success of new Apple product to rabid fanbois affected by the reality distortion field
  3. Attribute longer term success of product to stupidity of consumers
  4. Purchase previously scorned product for stupid relatives so they stop bothering you to help support the open source version of Apple product sold by Super Lucky Technology Extreme Inc. that you convinced them to buy
  5. Purchase previously scorned product for yourself just to see what all the fuss is about
  6. Admit that you now own and use the product, but complain about the product’s lack of SD card slot on random Internet forum
  7. Forget prior criticism of product, claim that it was revolutionary and an example of how Apple used to be really innovative, but has now lost its edge

Rinse and repeat
Author: The Real Blastdoor on Tue Jun 01, 2010 8:05 am

So true!

Via Stream of Superior Consciousness

18
To Tumblr, Love PixelUnion