Swiping Table View Cells

In my opinion the best UI designs are ones that allow users access to and the ability to modify as much information in as possible in as little time as possible. A recent trend in table views has significantly expedited the process of modifying the contents of a table view very quickly and intuitively. This is a blog post about one of my favorite UI based cocoa pods, MCSwipeTableViewCell.

mugatu

Mailbox started this trend almost two years ago with their wildly popular third party e-mail app. What they do is give you a standard looking table list view with relevant mail information on each cell. However as the above diagram shows it also gives you the option to swipe the cell to trigger code blocks. In this case a swipe right reveals a check mark to mark the mail as read and remove it from the stack, and a swipe left reveals a yellow deferral option that triggers a popup menu to give you deferral choices in case you want to revisit the mail even though you wish it to disappear form the inbox stack. Now even google has gone on board and made their own implementation of this functionality with their inbox app.

MCSwipeTableViewCell

Enter the MCSwipeTableViewCell gitHub repo slash CocoaPod by AlikaRagoz. As the above gif demonstrates it gives you the option to give this functionality to any table view cell in your app and specify multiple swipe triggers for any actions you want to give them. Not only does it give you the single swipe left or right functionality of the mailbox app, it gives you different triggers at different swiping distances incase you need more functionality. The background color/icon, swipe distance, block functionality and even some delegate options are all configurable and in my app, “Tasks” I make use of these to handle task “snoozing”, completions and moving tasks from the inbox to different user generated lists.

How To Use

After creating a podfile, init’ing it, and installing your pods you will need to include it in your table view controller class. Then you need to start creating instances of the MCSwipeTableViewCell, usually within the cell dequeuing method that all table view controllers call when generating table view cells.

cell.firstTrigger = 0.1;
cell.secondTrigger = 0.6;

UIView *checkView = [self viewWithImageName:@"check"];
UIColor *greenColor = [UIColor colorWithRed:85.0 / 255.0 green:213.0 / 255.0 blue:80.0 / 255.0 alpha:1.0];

UIView *crossView = [self viewWithImageName:@"cross"];
UIColor *redColor = [UIColor colorWithRed:232.0 / 255.0 green:61.0 / 255.0 blue:14.0 / 255.0 alpha:1.0];

UIView *clockView = [self viewWithImageName:@"clock"];
UIColor *yellowColor = [UIColor colorWithRed:254.0 / 255.0 green:217.0 / 255.0 blue:56.0 / 255.0 alpha:1.0];

This bit of code first sets up a UIView that becomes apparent behind the sliding table cell when the user swipes it. The first line just sets the view up with the desired graphic to show up, in our case a check mark, a clock and a cross. The second line for each view setup just sets the color it will use later.


[cell setDefaultColor:self.tableView.backgroundView.backgroundColor];

[cell setDelegate:self];

Then we will tie our sub-classed MCTableViewCells together in the dequeue with the background views we previously defined and a block of code or selector defining the action that occurs once the swipe is over. The code for that is below:


[cell setSwipeGestureWithView:clockView color:yellowColor mode:MCSwipeTableViewCellModeSwitch state:MCSwipeTableViewCellState3 completionBlock:^(MCSwipeTableViewCell *cell, MCSwipeTableViewCellState state, MCSwipeTableViewCellMode mode) {
NSLog(@"Did swipe \"Clock\" cell");
self.alertController = [UIAlertController alertControllerWithTitle:nil
message:@"Snooze the task!"
preferredStyle:UIAlertControllerStyleAlert];

UIAlertAction *snoozeTillTonight = [UIAlertAction actionWithTitle:@"Tonight"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action)
{
//set the time for the
}];
UIAlertAction *snoozeTillTomorrow = [UIAlertAction actionWithTitle:@"Tomorrow"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action)
{
//set the time for the
}];
UIAlertAction *snoozeTillNextWeek = [UIAlertAction actionWithTitle:@"Next Week"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action)
{
//set the time for the
}];
[self.alertController addAction:snoozeTillTonight];
[self.alertController addAction:snoozeTillTomorrow];
[self.alertController addAction:snoozeTillNextWeek];

[self presentViewController:self.alertController animated:YES completion:^{
NSLog(@"Presenting Alert View Controller");
}];

You may also want to define the background color when the swipe hasn’t reached the triggered action yet which you do with the first line in the above code. You may also want to set up the optional protocol delegates that the cell class provides.


// When the user starts swiping the cell this method is called
- (void)swipeTableViewCellDidStartSwiping:(MCSwipeTableViewCell *)cell {
// NSLog(@"Did start swiping the cell!");
}

// When the user ends swiping the cell this method is called
- (void)swipeTableViewCellDidEndSwiping:(MCSwipeTableViewCell *)cell {
// NSLog(@"Did end swiping the cell!");
}

// When the user is dragging, this method is called and return the dragged percentage from the border
- (void)swipeTableViewCell:(MCSwipeTableViewCell *)cell didSwipeWithPercentage:(CGFloat)percentage {
// NSLog(@"Did swipe with percentage : %f", percentage);
}

I’ve been heavily using this cocoa pod for my own personal app, Just.Do. Personally I love how it provides a quick and easy way to alter the meta-data associated with the tasks of a task manager that you’d normally have to dive into a detail view and make several extra taps or inputs in order to assert. Here, you just swipe left to reveal the yellow colored snooze view which then brings up the snooze alert view to allow you to put the task off to later the same day, the next day or next week.

SwipeCollage

This is great because now changing the due date of the task requires only two tap inputs that previously required selecting the task to take you to a detail view, tapping some kind of date/time picker and then finally saving those changes and going back to the list view for the next task. So hot!

Overview of Digital Systems & Computer Architecture: Sequential Logic & Memory

Sequential Logic:

Before we covered how to create complicated combinational logic that eventually lead to the creation of an ALU (Arithmetic Logic Unit), the most central part of a processor. These were however all operations that occur (nearly) instantly after the right input combinations were given. In computing we need to be able to store variables to make the right computations to them, and we also need to be able to store the program that the processor will use to execute the right instructions. In order to do this we need sequential logic, or logic that not only depends on the current input, but the previous output or state of the device.

The Digital Latch:

The most simple devices in digital electronics that store information from a previous state, are latches, and the easiest one to implement using gate or transistor level design is the SR-Latch, or Set/Reset Latch, as shown below.

440px-R-S_mk2

The common design element that allows the previous output of the device to dictate the current one is feedback. Below is a truth table that shows how each input and the previous state affects the outcome. Note how because the output of the SR latch is connected back into the input, the output of the latch now can stay in the same state when both inputs are low. Whenever the input is high on the set pin, the output becomes low, and the opposite is true of the reset pin. When both inputs are high however, something called a race condition occurs. This is a very important concern in digital electonics where the output of the device becomes unpredictable due to competing output assertions. The reason it is called a race condition is because both inputs are in a race to make their output assertion first. There are various ways to add complexity to the design to overcome this problem that are beyond the scope of these posts, remember I’m mostly interested in programmers becoming more aware of how their computers and their software work behind the scenes.

SR latch operation[13]
Characteristic table Excitation table
S R Qnext Action Q Qnext S R
0 0 Q hold state 0 0 0 X
0 1 0 reset 0 1 1 0
1 0 1 set 1 0 0 1
1 1 X not allowed 1 1 X 0

The Digital Flip-Flop

Yes, this device has a somewhat silly name, (engineers are very silly people deep down inside in the best way possible), but it is arguably one of the most important digital devices there are. What seperates a flip flop device from a latch, is that inputs and states are asserted synchronously at the edge of a clock signal. Without getting into too much detail, this allows digital systems to be easilier be synchronized to a shared system clock. In computers this is extremely important since so many different components have to work together so quickly. This becomes more clear when examining this signal pattern below for one of the most used sequential devices in digital electronics, the D-Flip-Flop.

Screen Shot 2015-07-10 at 10.00.47 AMFrom hyperphysics,

The D flip-flop tries to follow the input D but cannot make the required transitions unless it is enabled by the clock. Note that if the clock is low when a transition in D occurs, the tracking transiton in Q occurs at the next upward transition of the clock.”

So essentially, the device holds onto whatever the digital signal the input pin “D” has when the clock edge is reached. This design can be altered with some slight reconfigurations so that the output is only altered when both the clock and and a write-enable input is given. This creates what is one of the most important devices in computer architecture, the Register

Registers

From wikiBooks on Digital Circuits

Registers are groups of flip-flops, where each flip-flop is capable of storing one bit of information. An n-bit register is a group of n flip-flops. The basic function of a register is to hold information in a digital system and make it available to the logic elements for the computing process.
There generally two kinds of registers, serial registers and parallel registers. Serial Registers as the name suggests either take in data in one serial line, or send it back out in a serial line, or both. Parallel registers do the same with parallel lines equaling the number of bits they store. Typically in processor design they are parallel registers on both the input and out.

pload

RAM

A RAM cell is not very different from a register in that it uses feedback elements to hold an output state and to write to it when desired. The only difference is that you need to be able to stack them in rows and resolve how to read and write to the corret element when desired. Note that the cell design below is just for one bit of storage, for modern processors the bus is 64-bits wide which means each RAM element would have 64 of these cells arranged in each row so that you whenever you read or write to RAM it is in 64-bit or 4-Byte words.

Screen Shot 2015-07-10 at 9.34.08 AM

In most cases each word will also be arranged in columns to reduce the number of address selection lines needed to choose which RAM cells are written to and read from. Remember decoders? If we have an 8-bit system bus that directs an 8 bit decoder, that decoder can now select 256 rows of cells to read from, and if we combine that with a column decoder of 8 bits in width means that we get 256 columns of cells to chose from. Together that means 65,536 Bytes of RAM, such storage, wow. The only control inputs left in order to have full control over a RAM cell, are a clock pin to keep things synchronized, a chip enable (E) in the likely case we are using more than one RAM module and we need to choose which one is being used, a Write Enable (W) to indicate we want to write to the cell at the given address, and an Output Enable (O,or G) which is there so that we are only outputing one module to the bus at the same time.

Screen Shot 2015-07-10 at 9.49.06 AM

Screen Shot 2015-07-10 at 9.49.17 AM

And That’s it really for storage elements. Now that we know how to make complex combinational circuits and complex sequential circuits we can design a large portion of the devices necessary in processors. Tune in next time where we’ll go over the basics of how to coordinate all the data buses in a processor that routes data from various storage elements, to/from arithmetic and data modulation elemetns to/from the peripheral bus.

Refrences

  • My own professional and academic experience as an Electrical Engineer
  • Hyperphysics:
  • MIT OCW: Introduction to Digital Systems