Archive for March, 2011

Although I began today’s work by doing some work on the functionality for the buttons, I decided that I should get the layout itself working first, since in a pinch we can still use the dummy user object, even if the functions are still in-progress. This also means that I won’t have to keep remembering to disable the code every time I commit, since the layout was crashing.

I quickly realized that the login screen would never fit nicely into a horizontal orientation on the iPhone, so I locked the rotation on those devices to just portrait orientations. It can still rotate upside down for those though. For the iPad, I needed to start figuring out how to get it to look good on the bigger screen, which meant doing some resizing work.

I’ve had issues with resizing before, with the multi-cell view, and I had solved it at the time using a whole load of conditionals and hardcoded values. This time, I wrestled with it in a different way, trying to utilize some automatic methods which I hadn’t been able to get working previously. Eventually, I managed to use the autoresizingMask and autoResizesViews properties to get some automatic layout fixes even through rotation. Ironically, it doesn’t really resize that much yet, but it is still much improved to before, as you can see.

I spent a while fiddling with autoresizingMask, testing various restrictions on how the resizing works. I ended up using UIViewAutoresizingFlexibleLeftMargin and UIViewAutoresizingFlexibleRightMargin in conjunction to get an automatic recentering. I played around with the top and bottom margins, because a centering would be nice vertically as well, but it appeared to force each element to space out, which made it look awful.

Some issues remaining are how the version and iPhone link elements are skewed. I’m pretty sure that this is because they are the only elements that didn’t start with a centered location. This means that the subsequent automatic resizing/repositioning is skewing it to match the iPad screen.

I tried to fix the vertical centering by editing the bounds for the view, but the bounds settings appeared to be ignored, no matter how I went about it. As I recall, problems with this were one of the reasons I ended up with such an ugly solution for the multi-view cell. I ended up doing a similar thing here, with a vertical adjustor variable. However, instead of being purely hard-coded, I based it on the center of the view itself, and I definitely want to fix this later. It isn’t a perfect solution, as it is not perfectly centered when rotated, since the adjustor doesn’t actually…adjust automatically. Again, still a work in progress.

Next I need to play around with the actual resizing aspect. I’m thinking of trying for a more square-shaped interface on the iPad, because it would be more like the sheet modal view (though this is a full-screen modal view). Hoping for the same kind of cleanness that sort of view has. I also need to fix that vertical centering.

Finally, after that’s all set up I need to put in the functionality itself. I spent a while thinking about how to do this, and I think it’ll be done in stages, so that it has some sort of pseudo-functionality at each stage until it’s fully working.

For the login fields/button, I’ll start by having it set the singleton user object with the given fields, without any actual server communication. This won’t be a real “login”, but will let the application feel like it is, with the password editable in personal info (username isn’t editable), even though it isn’t persistent. After this will be the actual implementation of the server communication for login, with the associated success and fail cases.

The create user button will be the same, starting with a very similar screen to the personal info screen, where the username, password, and other information can be input. The first version will simply write this to the user object, like before, allowing for the appearance of the full functionality (within a session). The second will have to do the server communication and processing.

I’m not actually sure what the iPhone link thing is supposed to do, functionally, so that’ll be included last.

The world’s lamest screenshot below! There’s a point…really!

I haven’t updated in a while, been swamped by a bunch of projects and take-home exams. I started out today working on the View Recommendations feature, trying to figure out how it would work and how to go forward. I made the view itself and ended up linking it to the (in-progress) recommendation manager, which I believe will eventually hold all of the recommendation information and will also handle the communications with the server for them. Unfortunately, it doesn’t actually show anything right now since the manager itself is not fully implemented right now.

During the Wine Agent meeting Evan seemed sort of confused about why it was marked as critical (which is why I started working on it) and suggested that I work on the login screen instead. Since I had been thinking of doing that in the first place, only choosing otherwise due to the recommendations view being marked as critical, I immediately switched over. The login screen was the logical next step after the sort of finished personal info page, since that will only have real functionality once the global user object is actually enforced and initialized at the start (if not already logged in).

First was deciding how to implement the login screen, as in where and when it should force the user to login or register as a new user. I began thinking that this would be done as a full-screen modal view that appears upon application startup if the user object is nil. However, I began working on this thinking I would be able to call it from the application startup loop, which failed since it cannot present a modal controller from itself.

I ended up messing up a few more times before finally setting up the user object check in the application startup, and if the user object is nil then it will set the starting tab to the User one. This part will be temporary, since I will eventually want to allow the application to load the tabs exactly the same way as it usually does depending on where the user was last, but for simplicity in implementing the modal popup I did it this way. Once I get it all finalized then I can go through and add the delegate capabilities for presenting and dismissing the modal view to everything, I suppose. Unless it could be any view, which would be painfully tedious and hard to maintain. I’ll need to do some testing on which pages can actually be accessed upon startup.

Anyhow, once I had it defaulted to the single user screen if the user object was nil, I implemented the actual presentation of the login view controller in a modal view. This screen will probably be mostly or completely redone, but you can see what the old login screen used to look like in the screenshot. It crashed for a while due to bad memory accesses, but they were eventually sorted out.

The next step will be figuring out how to reimplement the UI itself so that it fits on all the devices and also functions (it crashes currently whenever I try to hit any of the buttons).

This post actually covers all the work since the last update, since I’ve been more focused on the actual work than writing up the post. Sorry about that, but at least I remembered to take screenshots this time!

The first step was creating and setting up the actual user object, which was fairly simple. We already had a User class so it was a simple matter of altering it, adding an instance to the personal info view controller, and adding some code so it correctly displays the current data as part of the options.

I began working on the next part, which was to add the edit functionality to each button. I had originally intended to do this by having each button bring up a keyboard, whose results would become the new data associated with that button. However, after talking with Evan we ended up editing this plan drastically. The new plan calls for several changes. In terms of the areas being displayed and edited, we need to have the first and last names be editable, instead of the username, which will be constant.

Also, instead of having it be an additional view on the existing navigation controller, it will be done via a modal controller. This change was the first that I did, since I have done similar changes before and knew what I needed to do. You can see in the screenshot that there is a done and reset button. Depending on how the data moves, I may have it set so that the reset button can restore the original values of each button. This would assume that the modal data is not committed to the actual user object until the done button is pressed. On the other hand, if we simply have every edit change the user object, then this reset button will be removed, and the done button may be reworded to Back to prevent confusion about this.

Finally, instead of having the current value on the right side of the cell, Evan wanted me to match some of the other cells in the application by having an editable text subview in the middle of the cell that has the current value defaulted to it. This subview will bring up the keyboard when pressed, which will edit that value. In the screenshot you can see that I have been trying to implement this on the username, but have not had any success.

Eventually, I figured out that it was stemming from an error I had made in the initialization checks, where I had actually made the case for when the subview already existed, but forgotten to make it in the first place, and was able to get the text field instead of the read-only subtitle thing. With that done with, I went ahead and changed the username to first name and last name to match that part of the design change and extended the text field change to all four areas.

The next part was to get the field to actually do something. I ran into several issues here, because the delegate function called from the text field just has the text field as an argument, without any reference to which text field it actually is. I eventually resolved this after playing around with the text field tags, which involved several small oops moments where I had to wrestle with NSLog and some silly things where I was thinking way too hard about how to get from the textfield to the cell view, before remembering that I had already set tags. With a few tweaks to make sure each option gets its own unique tag and some test outputs, I had an easy way to identify each text field.

From there, it was just a matter of setting up some conditionals and writing to the user object.

One interesting note about the behavior that I haven’t figured out if it is required is the fact that the user must hit Return before it actually saves the new data to the object. This is due to how the delegate function is called, and I don’t see any immediate solution if we want to do this differently.

Also, the personal info has a similar issue as the preferences where the data is not persistent across runs. Within a single run it does persist, however, as seen in the screenshot where the previous screenshot’s edit has taken hold and is now the initial displayed value.

I also removed the reset button, since each edit affects the user object directly (and so there is no way TO reset currently…although if you hit Done without hitting return it won’t save and so this is an indirect way of getting that behavior!).

And yes, I did get the password to work the way I wanted, where it always displays it as the right number of * for the password, without displaying it. I was amused the first time I tested it because I entered some gibberish and iOS tried to autocorrect it and got Cthulhu.

Today I began my usual planning and preliminary work on the next section I’m working on, the personal info view. This view will eventually allow the user to change their username, e-mail, and password. Of course, that will need the login screen to actually be reactivated, so that there is something to change!

As part of the planning, I basically just looked at the existing classes to try to see how the user information itself is going to work. I know that at some point we will be reactivating the login screen. As such, I tried to look to see if there were any existing objects containing the user information. Although there appears to be such a user class, as well as a login class, I did not see any actual instances, which will likely be created for the application when we reactivate the login screen. This means I will likely create this personal info page with a dummy user at first, until I can integrate it later with the login screen.

Knowing that, I started to think about how the layout was going to look like. The screenshot shows an initial creation of the view, though I am debating about whether to do it in 3 sections or just the one. If I keep the current layout, the current data will be displayed on the right side as the second information block on the button, and clicking the button will bring up a screen where the information can be edited via keyboard.

The next part is to create the dummy object and figure out how the edit screens will work.

Hm, forgot to post this yesterday. The last two days were spent fixing up the last of the previous changes and finalizing that they work, the preferences section. One thing that had not been done in the last iteration on them was making each area editable. This was fairly straightforward, where I just had to set up the initialization to take the existing data and start up that way. It got a little bit more complicated when returning, where it would add it, but would also need to remove the old entry.

My initial attempt to do this seemed to work, but caused several odd issues with areas seeming to disappear because of when I was removing cells and reloading the table. Fixing this did not remove all of the bugs, and also showed me another bug where it would remove the cell even if a new one was not added, such as if I simply cancelled the edit window. To fix both issues, I reworked when I was removing it to only happen on return, with conditionals for both cancelled and completed generators.

After getting this to work for the simpler food and wine preferences, it was pretty easy to extend my changes to the recommendation preferences as well. After fixing that, making sure it works on both devices, and fiddling with the timing to make the transition smoother, the preferences looks good now.

Another issue that popped up was from Evan’s testing, where he is currently working on a new split view of the menus, which has been floating around for a while but is finally being implemented (a week before it needs to be shown, no less). Because of the incredibly annoying way the multi-cell view does not receive the autoadjust, it had to be tweaked carefully for each orientation on each device, using a series of conditionals. All of this is further complicated by the new layout, which introduces yet another view on top of it as well as a different view size to boot. Basically, it all broke again. Evan said he would take a look at it, because he wanted me to focus on the next area, which is to create a Personal Info view, where the user should be able to view and modify their username, e-mail, and password.

Trying to quickly finish the existing issues with the multicell displays and preferences stuff so I can get started on the new tasks. The multi-cell work went fine, which is probably because I’ve gone to war against it so many times that I’ve pretty much memorized which issue, section of code, and fix is needed for each error. Just needed to resize it on iPad, because it worked on iPhone, which is probably what made it slip past me the first time. The menu view had some additional rotation issues where there were really weird resizing issues when coming back from the Twitter window, but I had already encountered the same type of problem before and quickly fixed that up.

Hoping to look at Preferences tonight/tomorrow, where I need to make the various options editable and also do a final check of everything to make sure no lingering bugs are around. Wednesdays are always unpredictable because I have unpredictably long meetings for my SD&D project and I still need to finish up some other assignments for Friday, so we’ll see how it works out.

Today’s All-Hands meeting was interesting, although most of it didn’t really apply to me such as budgeting and travel changes. They are moving them to a monthly meeting because they felt that the time wasn’t really being used well, what with people reading e-mail and such. I admit that I was actually working on Wine Agent during the meeting, but I was paying attention! They’re going to try to have status updates from everyone at that time as well. My only thought about the idea was that it seems like the meeting is going to overload now. It will take time for everyone to give their update, and then I assume that presentations will all be compacted as well, but I guess we can’t know unless we try it out.