I have a static background image (map) that loads in my ImageView. I have a couple of transparent text images (labels for cities on the map, for example) that I would like to overlay on the map upon the click of a button. re-clicking the button would unload the layer so that the user could have any combination of the layers selected depending upon what they would like to see. I might have a total of 5 layers connected to 5 buttons.
I know it is simple, but I need some help with the button code. If I have a button called 'cities' and a layer called 'cities.png' I would like to load and display over my main ImageView map, could someone please please please show me some code that would allow the button click to cycle my cities.png layer on and off?
many thanks
Make a property of ImageView and synthesize it
Add a gesture recognizer to your view(Google it);
Add a tap count of 1 to fire function
In function
check
if(self.imageView.image != nil)
{
self.ImageView.image = [UIImage imageNamed:#YourImage"]; //load the image view
}
else
{
self.imageView.image = nil; //image already dispelled..remove it.
self.imageview.center = //touch location center //
}
This will work if you want to load one image at a time
Related
I have 25 UIControls and 10 UIImageView. It looks like this:
Now the images are the UIImageVIews and the grids are the UIControls. What I want is when the user taps at a image and then taps at any of the grids (any blank grids of-course) the UIImageView is then removed from the current superView and added as the subView of the blank grid tapped. For example, if the user taps at the A1 grid first and then in the B2 grid, two actions occur,
UIImageView from A1 grid is removed,
UIImageView is added to B2 grid
This means when the user taps at the image at A1 grid and then taps at the B2 grid, the output window looks like this:
EDIT
So, at a time I need to have track for two UIControls:
1.which one is pressed first, and
2.which one is pressed second. And then remove the UIImageView from the first UIControl and add it to the second UIControl. I have tried giving the UIControls a tag like,
//....
A1.tag = 1;
//...
-(void)a1ViewTapped:(id)sender
{
int i = A1.tag;
[self switch:i];
}
//...
-(void)switch:(int)_tag
{
//....
UIView *view = (UIView*)[self.view viewWithTag:_tag];
[view removeFromSuperview];
//...
}
By this I can track a single UIControl, but need to track two of them.
How can I accomplish this, can anyone help?
UIControl inherits from UIView, so you can add a subview to your UIControl by calling addSubview:.
You can remove your UIImageView from the previous control by calling removeFromSuperview on the UIImageView
edit:
A very simple implementation would be to create a property that holds a reference to the selected UIControl. When the property is nil, then you are in selection mode. Touching up inside a control puts a reference to the control into the property. When the property is not nil, you are looking for a grid control in which to place the image.
You'll also need a way to keep track of whether your UIControl has one of the UIImageView instances as a subview. There are a number of ways to do that. One way would be to subclass UIControl to add a property to it that points to the UIImage it contains. Another way might be to simply examine the subviews of the UIControl to see if it contains one of the images in question. Another way would be to create some data structure to keep track of the positions of the images. How you do it is up to you, and the best way depends on the specifics of your implementation.
Just for the sake of discourse, let's assume you set up an NSMutableDictionary called imageMap that uses the tags of your UIControls as keys and sets references to the images as values. Then you could do something like:
-(void)selectGridControl:(UIView*)view
{
if (selectedControl == nil) // In this case nothing is selected
{
selectedControl = view;
}
else // In this case we are moving the image to the new view
{
UIImageView *selectedImage = [imageMap objectForKey:selectedControl.tag];
if (selectedImage != nil)
{
[selectedImage removeFromSuperview];
[view addSubview:selectedImage];
[imageMap removeObjectForKey:selectedControl.tag];
[imageMap addObject:selectedImage forKey:view.tag];
selectedControl = nil;
}
}
Initializing imageMap and handling cases when the destination control already has an image are left as exercises for the reader.
Is it possible to pan a UIImageView and when it intersects with the frame of another UIImageView, have that other UIImageView be pushed around by the other UIImageView without just passing over it? I hope that makes sense!
If it is possible, could you give me some ideas on how I'd go about implementing this?
I imagine it would go something like...
If frame intersects frame from left or right on the x/y axis, have the other frame move in that same direction with same distance as the pushing frame. While that logic somewhat makes sense to me, I'm not sure how I'd implement that in code.
I'd really appreciate any advice you can offer.
So, you're only concerned with left / right panning...
Let's assume you have 2 UIImageViews, a & b, as subviews of some other UIView and defined as class members of some class.
You can get help detecting panning gestures (dragging touches) on each of these views by creating instances of UIPanGestureRecognizer and adding them to each UIImageView using method addGestureRecognizer:
When creating each UIPanGestureRecognizer, you need to designate a selector to receive the gesture events. Let say it's called didMove:
Now, some sample code:
- (void) didMove:(UIPanGestureRecognizer*)recognizer {
UIView* view = [recognizer view];
// Remember our UIImageViews are class members called, a & b
//
UIView* otherView = view == a ? b : a;
if (recognizer.state == UIGestureRecognizerStateBegin
|| recognizer.state == UIGestureRecognizerStateChanged) {
// Moving left will have a negative x, moving right positive
//
CGPoint translation = [recognizer translationInView:view.superview];
view.center = CGPointMake(view.center.x + translation.x, view.center.y);
// Reset so we always track the translation from the current view position
//
[recognizer setTranslation:CGPointZero inView:view.superview];
if (CGRectIntersectsRect(view.frame, otherView.frame)) {
// Translate by the same number of points to keep views in sync
//
otherView.center = CGPointMake(otherView.center.x + translation.x, otherView.center.y);
}
}
}
It may not be exactly what you need, but it should give you a good idea how it could be done.
Sounds like you'd better use something like Cocos2D with it's sprites, intersections and some basic physics...
You can do it like this,
First, Create an UIImageView and assign an UIImage to it.
Second, When the user swipes or makes any gesture just change the coordinates of the card by setting its frame again.
Since u want the card to slide away, you have to change the x coordinate to a negative value such that it slides off from the view.
The above said code of reframing the imageview should be given within a UIView setAnimation group of methods...with a required delay.
To achieve the push effect have a method called within the the same animation block of codes which creates a new imageview (having same name as that of first imageview) and keep it out of the view. That is beyond the width of the screen. (dont forget to release the card which was pushes away previously)
Then subsequently again make a new frame for this imageview such that it appears in the centre of the screen....When above three steps of code are put within the animation block of code for UIView or UIImageView with a delay time , u will achieve the required effect.
Hope this helps....
happy coding....
I have an NSMutbleArray with images. I puted the first image in UIIageView and then I want that the user navigate between images. Should I make button or there is other method? Can I do it when user touch the image, like photo on the ios?
I have another question please. Some time I see this kind of button, but when I select .xib , I don't find them?
I have only basical button on object libraries
help please ( and sorry about my english )
Please watch the "Designing Apps with Scroll Views" talk from WWDC 2010.
Start here, log in, then look for that title, then click 'Watch in iTunes'.
Ummmmm, for a place to start:
-(void)viewDidLoad {
UIButton *image = [UIButton buttonWithType:UIButtonTypeCustom];
[self setCurrentIndex:0];
[image setImage:[array objectAtIndex:0] forState:UIControlStateNormal];
[image addTarget:self action:#selector(nextImage:) forControlEvents:UIControlEventTouchUpInside]
[[self view] addSubview:image];
}
-(void)nextImage:(id)sender {
UIButton *button = (UIButton *)sender;
[self setCurrentIndex:[self currentIndex] + 1];
if([self currentIndex] >= [array count]) {
[self setCurrentIndex:0];
}
[button setImage:[array objectAtIndex:[self currentIndex]] forState:UIControlStateNormal];
}
You will need to keep a reference variable named currentIndex to keep track of where you are in the array and which image to display the next image. This is a pretty awkward way to do it, but probably the easiest to understand and fastest to code.
To answer your second question: Those buttons are for mac applications, not iPhone applications. You will not see them when you create a xib because the iPhone doesn't support them.
Let me answer your second question first. The little control next to the pop-up menu controls how the library items are displayed:
Regarding your first question, I suggest you use swipe gesture recognizers. First, in your view controller, make actions for the swipe recognizers to send:
MyViewController.h
- (IBAction)showPriorImage;
- (IBAction)showNextImage;
MyViewController.m
- (IBAction)showPriorImage
{
// You'll need to change this based on how you track the current image.
if (self.currentImageIndex > 0)
self.imageView.image = [self.images objectAtIndex:--self.currentImageIndex];
}
- (IBAction)showNextImage
{
// You'll need to change this based on how you track the current image.
if (self.currentImageIndex < self.images.count - 1)
self.imageView.image = [self.images objectAtIndex:++self.currentImageIndex];
}
Then, in your XIB, find the swipe gesture recognizer in the library:
Drag a swipe gesture recognizer onto your image view. In the Attributes Inspector, set the swipe direction to Left. Then find the recognizer in the object list (on the left side of the XIB) and control-drag from it to File's Owner. Choose showPriorImage from the pop-up.
Now drag another swipe gesture recognizer onto your image view. Set its swipe direction to right, and connect it to the showNextImage action on your File's Owner.
I am trying to change the look of the tableviewcells by adding columns. I know the normal tableview doesn't allow this. Can someone point me in the right direction to achieve something similar to the attached image? The basic functionality is to have a grid of cells. 3x3 and any of the 9 cells can be clicked and it opens another page. its similar to the image picker but instead of images it would be cells with subtitles etc.
http://www.bronron.com/apps/IpadMenu.jpg
Any ideas?
Thanks in advance.
I would recommend that you try using a UIScrollView instead of a UITableView for this.
Each item in your menu can be a UIImageView, or a UIButton which you add as subviews to your UIScrollView.
The following code can be insterted in viewDidLoad inside your view controller and assumes that you have setup your UISCrollView in interface builder, otherwise you would need to allocate your scroll view inside viewDidLoad.
The code will add a variable number of menu items to a UIScrollView with two columns. To deal with user input you can make all the menu items UIButtons which call associated IBAction methods, or in this case the menuItems are you views, so you can identify which menu item the user is touching by looking at the users touch location within the scroll view, and then carrying out the appropriate action based on this.
UIImageView *menuItem = nil;
//The x and y view location coordinates for your menu items
int x = 0, y = 0;
//The number of items you want in your menu
int numOfItemsToAdd = 10;
//The height and width of your menu items
int menuItemHeight = 50, menuItemWidth = 50;
//The content seize needs to refelect the number of menu items that will be added
//The hieght of the ocnten size is calclutated by multiplying the menu item height by the number of
//menu items devided by the number of menu items that fit across in the width of the view.
[scrollView setContentSize:CGSizeMake(320, menuItemHeight*numOfItemsToAdd];
for(int i=0; i<numOfItemsToAdd; i++){
if(i%2 == 0){//% the number of columns you want in your menu
x = 0;
if(i!=0)
y += menuItemHeight;
}else{
x = menuItemWidth;
}
menuItem = [[UIImageView alloc] initWithFrame: CGRectMake(x, y, menuItemWidth, menuItemHeight)];
//set the center of the menu item in the scroll superviews coordinate system
menuItem.center = CGPointMake(x, y);
//Add the name of the image you want for the menu item
//These strings could be stored in an array and retrieved in order
menuItem.image = [UIImage imageNamed:#"MyImage"];
//Finaly add the menu item to the scorll view
[scrollView addSubview:menuItem];
}
You can go for multi column grid table view layout , where you can define each and every row and column.
you can check this tutorial for Drawing a Grid in a iPhone UITableView – Tabular Cell Data
http://www.iphonedevx.com/?p=153
This is a completely custom view layout and IMHO, not really suitable for a table view. As with anything custom there are many ways to achieve what you want. Here's how I would approach this implementation myself. There may very well be some good open source implementations out there.
GridViewController : UIViewController
This is the top most view controller and has a UIScrollView containing 1 or more pages of GridView objects. This view controller would communicate with a dataSource that provides 0..N objects to display on the individual grid views.
GridView : UIView
Each grid view would be a custom UIViewSubclass that knows how to layout 0 to N objects as dictated by the data provided by the GridViewController dataSource. Each icon in the grid would be an appropriate UIView subclass, maybe UIButton or UIImageView or maybe custom depending on what it needs to look and act like.
More behavior would be added as needed to drag icons around, create new pages, persist state in the data model, etc etc.
Is there any way to change the image of the reorder control that is displayed when the UITableView is in edit mode? I have a UIImage that I’d like to display instead of the usual grey bars.
Do I have to subclass UITableViewCell to accomplish this?
I guess you're a long way past this by now, but this has come up in a new question.
See my answer here:
Change default icon for moving cells in UITableView
I recently ran across the need to change the image for the reorder control, because I subclassed UITableViewCell to provide my own custom table cell. As part of this effort, I changed the background of the cell to something other than the default color.
Everything works correctly, but when I put the UITableView into editing mode, the reorder control would appear, with a white background - instead of the background color I was using for the cell. This didn't look good, and I wanted the background to match.
During the course of various versions of iOS, the hierarchy of views in a UITableViewCell has changed. I've taken an approach that will traverse the entire set of views until it finds the UITableViewCellReorderControl private class. I believe this will work for iOS 5 and all subsequent iOS versions at the time of this answer. Please note that while the UITableViewCellReorderControl class itself is private, I am not using any private API's to find it.
First, here's the code to scan for the reorder control; I'm assuming that the text "Reorder" will be in the class name - which Apple could change in the future:
-(UIView *) findReorderView:(UIView *) view
{
UIView *reorderView = nil;
for (UIView *subview in view.subviews)
{
if ([[[subview class] description] rangeOfString:#"Reorder"].location != NSNotFound)
{
reorderView = subview;
break;
}
else
{
reorderView = [self findReorderView:subview];
if (reorderView != nil)
{
break;
}
}
}
return reorderView;
}
In your custom UITableViewCell subclass, you will override -(void) setEditing:animated: and find the reorder control here. If you try to find this control when the table is not in editing mode, the reorder control will not be in the view hierarchy for the cell:
-(void) setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing:editing animated:animated];
if (editing)
{
// find the reorder view here
// place the previous method either directly in your
// subclassed UITableViewCell, or in a category
// defined on UIView
UIView *reorderView = [self findReorderView:self];
if (reorderView)
{
// here, I am changing the background color to match my custom cell
// you may not want or need to do this
reorderView.backgroundColor = self.contentView.backgroundColor;
// now scan the reorder control's subviews for the reorder image
for (UIView *sv in reorderView.subviews)
{
if ([sv isKindOfClass:[UIImageView class]])
{
// and replace the image with one that you want
((UIImageView *)sv).image = [UIImage imageNamed:#"yourImage.png"];
// it may be necessary to properly size the image's frame
// for your new image - in my experience, this was necessary
// the upper left position of the UIImageView's frame
// does not seem to matter - the parent reorder control
// will center it properly for you
sv.frame = CGRectMake(0, 0, 48.0, 48.0);
}
}
}
}
}
Your mileage may vary; I hope this works for you.
Here is my Swift solution based on Rick Morgan's answer:
func adjustSize() {
// we're trying to leverage the existing reordering controls, however that means the table must be kept in editing mode,
// which shrinks the content area to less than full width to make room for editing controls
let cellBounds = bounds
let contentFrame = contentView.convert(contentView.bounds, to: self)
let leftPadding = contentFrame.minX - cellBounds.minX
let rightPadding = cellBounds.maxX - contentFrame.maxX
// adjust actual content so that it still covers the full length of the cell
contentLeadingEdge.constant = -leftPadding
// this should pull our custom reorder button in line with the system button
contentTrailingEdge.constant = -rightPadding
// make sure we can still see and interact with the content that overhangs
contentView.clipsToBounds = false
// recursive search of the view tree for a reorder control
func findReorderControl(_ view: UIView) -> UIView? {
// this is depending on a private API, retest on every new iPad OS version
if String(describing: type(of: view)).contains("Reorder") {
return view
}
for subview in view.subviews {
if let v = findReorderControl(subview) {
return v
}
}
return nil
}
// hunt down the system reorder button and make it invisible but still operable
findReorderControl(self)?.alpha = 0.05 // don't go too close to alpha 0, or it will be considered hidden
}
This worked pretty well. contentLeadingEdge and contentTrailingEdge are layout constraints I set up in Interface Builder between the contentView and the actual content. My code calls this adjustSize method from the tableView(_:, willDisplay:, forRowAt:) delegate method.
Ultimately, however, I went with Clifton's suggestion of just covering the reorder control. I added a UIImageView directly to the cell (not contentView) in awakeFromNib, positioned it, and when adjustSize is called I simply bring the image view to the front, and it covers the reorder control without having to depend on any private APIs.
I put a little work into this recently, but came up short. I tried setting my own editingAccesoryView but couldn't get the reorder control to change. Odd.
My guess is that it has something to do with the following comment in the UITableviewCell docs re: showsReorderControl:
If the value is YES , the reordering
control temporarily replaces any
accessory view.
In other words, the editingAccessoryView is being replaced by the reordering control view, which might be why we cannot override the reordering control. Hoping someone can find a workaround.
You set the cell's editingAccessoryView property to an image view containing the image you want.
As an aside, I would caution you to be careful when doing this. When you substitute a custom graphic for a system standard such as the reorder graphic, you run a serious risk of confusing the user. The standard UI grammar has told them to expect the standard graphic when reordering and they may not understand the significance of your custom graphic.
Maybe we're all overthinking this. :)
Just put a custom UIImageView over the top of the default move accessory so it covers it up. Done.