The design is that there is a return button in the headerView, but I can not get any response of the return button.
Here is some description of my code: I add a delegate in my headerView, so when I click the button in headerView, the UIViewController can return to the front one. I define a class to be headerView, and in this class I add the return button like this :
_returnButton = [[UIButton alloc] initWithFrame:CGRectMake(15, 20, 16, 20)];
_returnButton.userInteractionEnabled = YES;
_returnButton.clipsToBounds = YES;
[_returnButton setBackgroundImage:[UIImage imageNamed:#"return.png"] forState:UIControlStateNormal];
[self addSubView:_returnButton];
Then in the UIViewController, I create an instance of my headerView and add it to my UITableView:
ThemeHeader *headerView = [[ThemeHeader alloc] init];
headerView.delegate = self;
headerView.userInteractionEnabled = YES;
[headerView updateIfNeeded];
In the function updateIfNeeded, I add the target to my headerView, just like this:
- (void)updateIfNeeded {
NSLog(#"test delegate");
if ([self.delegate respondsToSelector:#selector(return:)]) {
NSLog(#"succeed");
[_returnButton addTarget:self.delegate action:#selector(return:) forControlEvents:UIControlEventTouchUpInside];
}
}
I can see the log "test delegate" and "succeed", but when I click the return button, it seems nothing happens, and I can not see any log. What's wrong with my code?
Try to modify
[self.contentView addSubView:_returnButton];
Related
SOLUTION: it was stupidly simple, I overlooked the need to declare the method for my button function in this implementation, the fix was simply adding this in the right spot (inside the implementation... duh!)
-(void)bugButton { //do stuff }
Found some code for a button that looked like what I wanted. After adding & compiling the button crashes my app when tapped, any idea why? Heres the entire cell, pretty new to making these so its hacked together from other stuff, the button stuff is near the top. I do have the method in a different place (and have used boring PSButtonCell's successfully so I know that the method works)
#interface harpButtonCell : PSTableCell <PreferencesTableCustomView> {
}
#end
#implementation harpButtonCell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(id)reuseIdentifier specifier:(id)specifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier specifier:specifier];
if (self) {
// icon
UIImage *bugImage = [[UIImage alloc] initWithContentsOfFile:[NSString stringWithFormat:#"%#/Bug.png", kSelfBundlePath]];
UIButton *bugbutton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 75, 75)];
[bugbutton setImage:bugImage forState:UIControlStateNormal];
[bugbutton addTarget:self action:#selector(bugButton) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:bugbutton];
/*
UIImage *paypalImage = [[UIImage alloc] initWithContentsOfFile:[NSString stringWithFormat:#"%#/Paypal.png", kSelfBundlePath]];
UIButton *paypalbutton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 75, 75)];
[paypalbutton setImage:paypalImage forState:UIControlStateNormal];
[paypalbutton addTarget:self action:#selector(paypalButton) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:paypalbutton];*/
//int width = self.contentView.bounds.size.width;
}
return self;
}
- (instancetype)initWithSpecifier:(PSSpecifier *)specifier {
return [self initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"harpButtonCell" specifier:specifier];
}
- (void)setFrame:(CGRect)frame {
frame.origin.x = 0;
[super setFrame:frame];
}
- (CGFloat)preferredHeightForWidth:(CGFloat)arg1{
return 100.0f;
}
- (CGFloat)preferredHeightForWidth:(CGFloat)width inTableView:(id)tableView {
return [self preferredHeightForWidth:width];
}
#end
It seems that you don't implement the action of button, try to add the action in the cell:
-(void)bugButton{
NSLog(#"you clicked on button");
}
vwInfo = [[UIView alloc]initWithFrame:CGRectMake(20, 85, 280, 100)];
[self.view addSubview:vwInfo];
I create a UIView programmatically on button tap.when i click it again i need to check vwInfo is visible or not.I can done this with a Boolean value.is there any other option to do this?
you can check if view is exist or not using isDescendantOfView but make sure you have to pass your vwInfo's superview to check view already exist or not.
if ([vwInfo isDescendantOfView:self.view]) {
//view already exist in self.view
}
else{
//view is not exist in self.view.
}
Is it because you do not want to add the UIView a second time when you already added it ?
In this case you could declare in your .h(header) file UIView *vwInfo;
and then in your IBAction for your UIButton:
if(vwInfo == nil) {
vwInfo = [[UIView alloc]initWithFrame:CGRectMake(20, 85, 280, 100)];
[self.view addSubview:vwInfo];
}
you can check with Tag Functionality. Assign tag to your view.
UIView * vwInfo = [[UIView alloc]initWithFrame:CGRectMake(20, 85, 280, 100)];
[vwInfo setTag:101];
[self.view addSubview:vwInfo];
On Button Click
- (void)buttonClick :(id)sender {
UIView * viewTemp = (UIView *)[self.view viewWithTag:101];
if(viewTemp){
NSLog(#"View is available");
if([viewTemp isHidden]){
NSLog(#"Your view is hidden");
}else{
NSLog(#"Your view is visible");
}
}else{
NSLog(#"View is not added yet");
}
}
UIView is accessible with the superview property
if([vwInfo superview]!=nil)
NSLog(#"visible");
else
NSLog(#"not visible");
I have a UIViewController with a tableView in it with CustomCells, the CustomCell load a PLAY Button for some of the cells, this button are generated within the CustomCell.m
- (UIButton *)videoButton {
if (!videoButton) {
videoButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
videoButton.frame = CGRectMake(120, 319, 50, 30);
[videoButton setTitle:#"Play" forState:UIControlStateNormal];
[videoButton addTarget:self action:#selector(PlayClicked:) forControlEvents:UIControlEventTouchUpInside];
videoButton.backgroundColor= [UIColor clearColor];
[self.contentView addSubview:videoButton];
}
playIMG.hidden = false;
return videoButton;
}
- (IBAction)PlayClicked:(id)sender {
TableView *tvvc = [[TableView alloc] init];
[tvvc PlayBtnClicked:[NSString stringWithFormat:#"%d", [sender tag]]];
}
in my TableView.m
- (IBAction)PlayBtnClicked:(id)sender {
NSString *tag = [NSString stringWithFormat:#"%#", sender]; //OK
int tagNumber = [tag intValue]; //OK
NSString *Media = [arrayID objectAtIndex:tagNumber]; //Not Getting Result !
NSLog(#"%#", arrayID); //Array is empty when logging it from this action
}
arrayID is NSMutableArray
arrayID = [[NSMutableArray alloc] init];
[arrayID addObject#"123"];
[arrayID addObject#"321"];
[arrayID addObject#"231"];
soo i checked the array by adding an action button in my TableView to log the array and its not empty.
how can i fix the empty array which is actually not empty ?
I solved the problem in much easier way than the delegate thing
removed
[videoButton addTarget:self action:#selector(PlayClicked:) forControlEvents:UIControlEventTouchUpInside];
and the action in the custom cell .m file
- (IBAction)PlayClicked:(id)sender {
TableView *tvvc = [[TableView alloc] init];
[tvvc PlayBtnClicked:[NSString stringWithFormat:#"%d", [sender tag]]];
}
in the tableView.m i added edited the action i want to link to this
- (IBAction)PlayBtnClicked:(UIButton*)button {
NSLog(#"Button Clicked Tag: %d", button.tag);
}
and in the cellForRowAtIndexPath method i added the action to the button in the custom cell
if ([MediaType isEqualToString:#"video"]) {
cell.videoButton.hidden = NO;
cell.videoButton.tag = indexPath.row;
[cell.videoButton addTarget:self action:#selector(PlayBtnClicked:) forControlEvents:UIControlEventTouchUpInside];//here linking the action to the button
cell.playIMG.hidden = NO;
}
now everything is working very well :)
The array isn't your problem - you're breaking the model-view-controller nature of the table view controller and its cells. If you want a control in the cell to call a method in the table view controller, make the table view controller the delegate of the cell, and call the delegate method from the cell's button.
If the code you've posted is correct, then you're creating a new table view instance in the PlayClicked method, which is definitely not the way to do it.
As a minor stylistic point, the Cocoa convention of method naming is camelCase, with a lower-case initial letter.
I have a segmented controll with two cells defined programmatically. When I go into my app both cells perform the same action. The first should open a webpage in Safari, the second opens an image and covers the current view for 5 seconds. Any pointers?
In the .m file
#property UISegmentedControl *segment;
- (void)viewDidLoad
{
UISegmentedControl *segment = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:#"Publication", #"About", nil]];
self.tableView.tableHeaderView = segment;
[segment addTarget:self action:#selector(segmentPressed:) forControlEvents:UIControlEventValueChanged];
[self.tableView registerClass:[UITableViewCell class]
forCellReuseIdentifier:#"UITableViewCell"];
}
- (void)segmentPressed:(id)sender {
if (_segment.selectedSegmentIndex ==0) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"******"]];
}else if(_segment.selectedSegmentIndex ==1){
UIImageView *imageView = [[UIImageView alloc] initWithFrame: CGRectMake(0, 0, 320, 480)];
imageView.backgroundColor = [UIColor redColor];
[imageView setImage: [UIImage imageNamed:#"MACSLoad#2x.png"]];
[self.view addSubview: imageView];
sleep(5);
imageView.hidden = YES;
}
}
You get that result because _segment is nil. You never assigned the segmented control you created to your property -- you assigned it to a local variable. So change this line,
UISegmentedControl *segment = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:#"Publication", #"About", nil]];
to,
self.segment = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:#"Publication", #"About", nil]];
Another way to do it, would be to get rid of the property all together, leave the code in viewDidLoad as it is, and change this,
- (void)segmentPressed:(id)sender {
if (_segment.selectedSegmentIndex ==0) {
to this,
- (void)segmentPressed:(UISegmentedControl *)sender {
if (sender.selectedSegmentIndex ==0) {
Unless you need to access the segmented control outside of its action method, there's no reason to create the property. It's better in any case to use the sender argument rather than a property (even if you have one) inside the action method.
I have two buttons for adding and deleting the textfields. Adding works fine but when I click on delete it deletes only the last added textfield. Here are my two methods:
-(void)addTextField {
keyTextField = [[UITextField alloc] initWithFrame:CGRectMake(10, yAxisDistance, 150, 30)];
keyTextField.borderStyle = UITextBorderStyleRoundedRect;
keyTextField.placeholder = #"Key Value";
keyTextField.delegate = self;
[self.view addSubview:keyTextField];
valueTextField = [[UITextField alloc] initWithFrame:CGRectMake(165, yAxisDistance, 150, 30)];
valueTextField.borderStyle = UITextBorderStyleRoundedRect;
valueTextField.placeholder = #"Value";
valueTextField.delegate = self;
[self.view addSubview:valueTextField];
yAxisDistance = yAxisDistance+35;
}
-(void)deleteTextField {
[keyTextField removeFromSuperview];
[valueTextField removeFromSuperview];
yAxisDistance = yAxisDistance-35;
}
I know it's an small issue but I am very new to this field so kindly help.
Use this code for remove specific textfield from UIView. But First you have to set tag of every UITextField in view when you create or add it in view.
for ( UITextField* textField in view.subviews )
{
if(textField.tag== 1)
{
[textField removeFromSuperview];
}
}
I think the problem lies with the outlet. Can you check the following:
Open the outlets that are connected to the textifeld in the IB. There should be gray dots inside circles on the left side of the editor. Are they seem correct for both text fields?
Setup a breakpoint inside deleteTextField method and check the two textfields. Verify that both properties are not nil.
PS: You don't need to add tags to your view, using properties is perfectly fine and even better in my opinion. The reason for your problem is something else. Also, you do not need to removeFromSuperview, you can also setHidden:YES.
Sorry that time I was not understand your problem...
I done with this:
Declare one
NSMutableArray *allTextfieldArray;
and initialise in
viewdidload
method..
now do:
-(void)addTextField {
keyTextField = [[UITextField alloc] initWithFrame:CGRectMake(10, yAxisDistance, 150, 30)];
keyTextField.borderStyle = UITextBorderStyleRoundedRect;
keyTextField.placeholder = #"Key Value";
keyTextField.delegate = self;
[self.view addSubview:keyTextField];
valueTextField = [[UITextField alloc] initWithFrame:CGRectMake(165, yAxisDistance, 150, 30)];
valueTextField.borderStyle = UITextBorderStyleRoundedRect;
valueTextField.placeholder = #"Value";
valueTextField.delegate = self;
[self.view addSubview:valueTextField];
yAxisDistance = yAxisDistance+35;
[allTextfieldArray addObject:keyTextField];
[allTextfieldArray addObject:valueTextField];
}
if ([allTextfieldArray count]>0) {
UITextField *txtField = [allTextfieldArray lastObject];
[allTextfieldArray removeLastObject];
[txtField removeFromSuperview];
txtField = nil;
UITextField *txtField2 = [allTextfieldArray lastObject];
[allTextfieldArray removeLastObject];
[txtField2 removeFromSuperview];
txtField2 = nil;
yAxisDistance = yAxisDistance-35;
}
you store the last textField in your variables keyTextField and valueTextField. So when you call your deleteTextField the last both will be deleted. you must track which textFileds you want exactly to delete.
for example you could give all your textFields a tag number when you create them:
first create an int as counter:
#implementation YourClass {
int tagcounter;
}
in init method set your counter:
tagcounter = 0;
in your addTextField:
keyTextField.tag = tagcounter++;
valueTextField.tag = tagcounter++;
when the delete button is tapped, you must know the textfield tags and pass them to your deleteTextField method. There you could do something like:
-(void)deleteTextFieldWithTag:(int)tagnumber {
for (UIView *view in [self.view subviews])
{
if ([view isKindOfClass:[UITextField class]])
{
if (view.tag == tagnumber || view.tag == tagnumber+1) {
[view removeFromSuperview];
}
}
}