How was this 'pop-up' view created? - iphone

Please see the image below.
How was this 'pop-up' view created? Suppose I wanted to completely imitate that view with the fonts, how would I do so?

There is not a SDK exposed component for this, but this could very easily be made using a hierarchy of views:
UIView - Main view. Uses a bezier path to create a protrusion to
point from the source. Has a border and drop shadow added to its
layer.
UIButton - Smaller font
UIButton - Larger font
UIButton - Change font type
UIButton - Container for sepia.
UILabel - "Sepia" text
UISwitch - turning sepia on and off
Just show and hide the view with an animation. Also, create delegate callbacks to tell the delegate when events occur in the popover.
// Delegate returns if the text can get smaller to enable/disable the button
- (BOOL) didSelectSmallerFont:(CGFloat)fontSize;
// Delegate returns if the text can get larger to enable/disable the button
- (BOOL) didSelectLargerFont:(CGFloat)fontSize;
- (void) didChangeFont:(UIFont*)font;
- (void) didToggleSepia:(BOOL)enabled;
etc.

The pyramid shape is not associated with the button that was clicked to present the popup. It would be a subview of the popup view, either a UIImageView or possibly drawn on a UIView, although a UIImageView would be the easier solution. You could definitely code the popup view to point that arrow at any point on the screen or in any direction. What I would do is instantiate the popup by means of an init method called initFromPoint:, then pass the center value of the button used to launch the popup. Then within the viewDidLoad method of the popup place the point appropriately based on the point.

Related

iOS: Add UIView to UITableView

I'm trying to add a UIView on top over the UITableView to mimic the iPhone Facebook style menu. I have it working fine by making the controller a UIViewController then adding a tableview however I am unable to make the menu a static menu unless the controller is a UITableView.
Is it possible to add a view ontop of a tableview and only make the tableview in the background scrollable without the view in the foreground scrolling?
Here is what I have with the subclass being UIViewController
But I am unable to make the tableview cells static via IB since it is not a subclass of UITableView Controller.
EDIT per NSJones Code:
It seems to be going somewhat in the right track. However the view still blocks the table. If I remove the view from the storyboard it will only display the table.
You can make a view hover the same way you make any real thing hover; Hold it up with something invisible.
Basically what you want to do is create a clear UIView (with user interaction disabled) that is the size of your view controller's view, and add it as a subview to your view controller's view property. That way it sits invisibly on top. then you can add a subview to that clear view and that subview won't move.
Edit:
It seems this nice clean approach won't work for you since you need your view controller to be a UITableViewController. The answer for this slightly more complex approach is to use a delegate method for UIScrollView which also works for UITableView. Apple has a fantastic demo of this concept in the WWDC2011 - Session 125 - UITableView Changes, Tips, Tricks video. If you can watch it I highly recommend it. The meat of this issue begins at about 36:10.
But to sum it up you implement the scrollViewDidScroll: delegate method. And handle the movement of the tableview by adjusting the position properties of the view. Here I am keeping an UIView property named viewToKeepStill still using this method.
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
// CGFloat stillViewDesiredOriginY; declared ivar
CGRect tableBounds = self.tableView.bounds; // gets content offset
CGRect frameForStillView = self.viewToKeepStill.frame;
frameForStillView.origin.y = tableBounds.origin.y + stillViewDesiredOriginY; // offsets the rects y origin by the content offset
self.viewToKeepStill.frame = frameForStillView; // set the frame to the new calculation
}
Instead of adding it as a subview of the table view, add it as a subview of the superview of the table view; that way it won't scroll.
So instead of this:
[tableView addSubview:viewController.view];
Do this:
[tableView.superview addSubview:viewController.view];
Assuming you want something that is visible full-time with the table, start with a view which contains both the menu view and the UITableView. Make the table smaller so it ends where the menu view begins. The table view can work with less vertical space.
If you have your UIViewController's view to be your table view then your table is going to span over the whole screen, so you won't be able to add anything on top of it.
Why not try the following:
1) create a new UIViewController
2) add a view on top where you want your menu
3) in the space left under just drag a table view from the component library
4) don't forget to set the 2 table view delegates to be your view controller class
that's about it?

NSPopUpButton, NSComboBox similar menu

I'm trying to create a menu with a drop down menu with a custom background for every cell.
First i tried to adapt NSPopUpButton but i couldn't find a way to change the cells background image. Using setImage: would slide the text to the right of the background. Next I stopped at NSComboBox but i couldn't find a way to change the arrow button. Can someone please help with and idea? Next thing would be to create a custom controller but i would like to use something already done.
To customise the arrow button in NSComboBox, you need to create a subclass of NSComboBoxCell and set your combo box to use that cell. If you've configured your control in IB, you can easily change the class of your cell there. If you're programmatically creating your combo box, create a subclass of NSComboBox, override + (Class)cellClass and return your custom NSComboBoxCell subclass from that method.
Now for the drawing. In your NSComboBoxCell subclass, you need to override
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView.
(I've tried overriding - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView but the cell frame it provides stops short of drawing the actual button area, i.e. it only covers the text input area.)
Your custom - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView should look something like this:
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
[super drawWithFrame:cellFrame inView:controlView];
// Constrain to the far right of the provided frame to draw the button
NSRect bounds = NSMakeRect(cellFrame.origin.x + cellFrame.size.width - cellFrame.size.height, cellFrame.origin.y, cellFrame.size.height, cellFrame.size.height);
// Draw your custom button inside the bounds rect
}
I'm not sure if I understood your question correctly. If you want to show a menu at an arbitrary position somewhere in your UI: NSMenu provides convenience methods for achieving that. Have a look at the documentation for + popUpContextMenu:withEvent:forView:, + popUpContextMenu:withEvent:forView:withFont: and – popUpMenuPositioningItem:atLocation:inView: to find the one that best fits your needs. Like that you can display a menu at whatever position you like.
If you instead want to display arbitrary content inside a menu, have a look at the documentation of NSMenuItem's - setView:. This allows you to insert views inside menus. Together with the above method of displaying menus wherever you want, you can create all sorts of solutions for "PopOver" needs.

How to add UIScrollView to Interface builder?

I have all my controls laid out in interface builder (many labels, buttons etc). How do I put them all in a scroll view in interface builder so that I can have more space and be able to scroll up and down to reveal more controls? Do I have to do this programatically?
Open the view that has all the controls and labels, etc. (in Interface Builder). Select All. Then under the Editor menu, select Embed In, then Scroll View.
Note: in older Xcode versions, this is under the Layout menu, then Embed Objects In... (scroll view).
My preferred solution, where you don't need to hard-code the size of the contentSize:
NB: you might be able to avoid the source-code parts of this using the trick here: https://stackoverflow.com/a/11239123/153422 - although I haven't tried it yet.
The rest of this trick ... you still need to use anyway
Move all controls into a single UIView (in IB: select all, then go Layout > Embed Objects In ... > View)
Hookup that single UIView to your source code using an IBOutlet property (see below)
IN SOURCE CODE, NOT INTERFACE BUILDER (IB is broken here, it has bugs where it sets the origin of the UIScrollView incorrectly - it tries to center the view. Apple never bothered to check it for basic bugs, sigh): Move the single UIView into a UIScrollView (see code below).
Use sizeThatFits to "automatically" set the correct size.
Code (StackOverflow won't let me put code inside a numbered list. Sigh)
Header file:
/** outlet that you hook up to the view created in step 1 */
#property(nonatomic, retain) IBOutlet UIView *masterView;
Class file:
/** inside your viewDidLoad method */
[scrollview addSubview: masterView]; // step 3
scrollView.contentSize = [masterView sizeThatFits:CGSizeZero]; // step 4
...although I haven't checked this recently, IIRC it works on both 2.x and 3.x
Select all the objects you want to put into a scroll view and go to the Layout menu, choose "Embed Objects In" and choose "Scroll View".
Its easy:
First add a scrollview to your view.
Change the size of the scrollview (e.g. make it 700 pixels long).
Start putting your controls
When you want to put/edit controls in the lower (invisble) part, select the scrollview and change the Y-start position to -300.
Voila.
After editing set the Y-start position back to 0 or whatever it was.
I don't know if it's just me, but I tried to follow the instructions in each of the other answers here and none of them worked. None of the answers included everything needed, each one I guess assuming we know to do something so leaving that part out. I finally figured it out with the help of red artisan. So... I am listing here ALL the necessary steps to get this to work:
In InterfaceBuilder, add a View and then add your controls to it (or if your controls already exist in the main view, you can select all your controls and then go to Editor | Embed In | View, then drag that new View so it is all by itself outside the main view). This View can be any size you like.
In InterfaceBuilder, add a Scroll View to your main view, and size it to take up the whole main view.
Add the code listed below to your UIViewController Header and Class files.
In InterfaceBuilder, hook up the View containing your controls to 'contentView' in the File's Owner. Hook up the Scroll View to 'scrollView' in the File's Owner.
Header File:
#interface MyViewController : UIViewController
#property(nonatomic, retain) IBOutlet UIScrollView *scrollView;
#property(nonatomic, retain) IBOutlet UIView *contentView;
Class File:
#synthesize scrollView, contentView;
- (void)viewDidLoad
{
[super viewDidLoad];
[self.scrollView addSubview:self.contentView];
self.scrollView.contentSize = self.contentView.bounds.size;
}
- (void)viewDidUnload
{
self.scrollView = nil;
self.contentView = nil;
[super viewDidUnload];
}
Although this question is very old, I will suggest a workaround I found as I had the same issue and wasn't able to find much help out there:
When in IB, if you want to place objects outside the 420 pixel, just make sure yourself of having selected Unspecified for all of Status Bar, Top Bar, and Bottom Bar for the View that contains the Scroll View with all the objects. This way, you'll be able to manually resize the screen (for the View). Then, you can follow Ximonn's advice on resizing the H value for the Scroll View, having access to all the other objects, working with them and then, undoing changes for H value and then setting the needed Bars.
Important little thing.
To scroll big subview (UIImageView for example) in UIScrollView remember, for this subview, uncheck "User Interaction Enabled" checkbox in InterfaceBuilder -> View window. Or do it programatically.
subview.userInteractionEnabled = NO;
Otherwise this subview will stack on screen without any effect.
I've been looking for this for a few days, and I finally came across this site with a solution that worked for me.
Scrolling with UIScrollView
Basically you have your main view with a UIScrollView object in it. Then another content view with all your content in it. Then you add the content view to the scroll view. And then finally set the size of the scrollview's content size to the size of the content view.
I know, this thread is a bit older... But somebody could find it on google, it's hight ranked.
I wrote this little helper Method to get the job done:
- (void)addSubview:(UIView *)theSubView toScrollView:(UIScrollView *)theScrollView
{
[theScrollView addSubview:theSubView];
theScrollView.contentSize = theSubView.bounds.size;
}
You just have to declare two IBOutlet's in the header (e.g. contentView and scrollView) and call the method like this, whereever you want to load a UIView into a UIScrollView with your sourcecode:
[self addSubview:contentView toScrollView:scrollView];
I called it in viewDidLoad
This method features iOS
The selected answer works well for Xcode 3.
However, for Xcode 4, menus have been re-arranged slightly.
To do the same in Xcode 4 select your views then use:
Editor > Embed In > Scroll View

iPhone dev: adding an overlapping label to the image

I'm trying to figure out a best way to implement the picture-editing capability shown in the native address book app on iPhone.
On the built-in address book, this is how the picture looks like before editing:
qkpic.com/2f7d4 http://qkpic.com/2f7d4
And after clicking edit, notice how "Edit" overlay is added and the image becomes clickable:
qkpic.com/fb2f4 http://qkpic.com/fb2f4
What would be the best way to implement something like this? Should I make the image a button from the beginning and have tapping disabled at first? If so, what steps are required to add an overlay/label to the image (in above example, gray border + the text "Edit" is added)
The easiest way is to use Interface Builder, create a container view, then add a UIImageView and UILabel as subviews to it. You would position and style the text and the image but set the UILabel to hidden. Make the whole container view respond to touches. It's easy to do since UIView is derived from UIResponder so all you have to do is override touchesEnded. Whenever you want to change the text label, just set the UILabel to hidden=NO.
There's more to it, however. Notice how the image has rounded corners? You'll want to override the UIImageView's drawRect method to implement a custom drawing routine to do that. There's lots of sample code around and it wasn't part of your original question so I'll stop here.

How do I programmatically make clicking on a UIImageView do something on the iPhone?

I have programmatically added a UIImageView. How do I make it send a message to my controller when the users clicks it, sending itself as the only parameter?
I wouldn't use a UIImageView unless there was some other compelling reason. I'd just use a custom UIButton and use the UIImage as its background.
Create a new class that extends UIImageView and use that.
In your class, override the touch events - touchesBegan, touchesEnded and/or touchesMoved as appropriate
From those methods, call back to a method on the controller.
I'd just put a custom button over the UIImage view, and use normally - buttons with Custom style are invisible and so will not obscure the image. It's also a great way to turn regions of text into clickable areas as well.
Or, you could assign the custom image as a graphic background for the button.
just put a button over the imageview, with the Alpha attribute set to 0.10 or less.
you can capture the button's tap event but almost cannot see it.