I want create custom UIActivityViewController. I create it and it works good. I have some elements in it and its ok. Now I place they in one line. How can I create UIActivityViewController with 2 lines of elements.
Now my code is:
- (id)init
if (self = [super init])
{
FacebookActivity *facebookActivity = [[FacebookActivity alloc]init];
TwitterActivity *twitterActivity = [[TwitterActivity alloc]init];
EmailActivity *emailActivity = [[EmailActivity alloc]init];
OpenInSafariActivity *openInSafari = [[OpenInSafariActivity alloc]init];
OpenInWebActivity *openInWeb = [[OpenInWebActivity alloc]init];
CopyLink *copyLink = [[CopyLink alloc]init];
copyLink.delegate = self;
facebookActivity.delegate = self;
twitterActivity.delegate = self;
emailActivity.delegate = self;
openInWeb.delegate = self;
openInSafari.delegate = self;
self = [self initWithActivityItems:#[emailActivity] applicationActivities:#[openInWeb, openInSafari, facebookActivity, twitterActivity, emailActivity, copyLink]];
self.view.backgroundColor = [UIColor redColor];
self.completionHandler = ^(NSString *activityType, BOOL completed)
{
};
}
return self;
And the second question is how can I set color of bottom view with all UIActivityViewController’s elements.
In the implementation of your custom UIActivity classes you need to implement the following class method:
+ (UIActivityCategory)activityCategory {
return UIActivityCategoryAction; // or return UIActivityCategoryShare
}
The return value defines which row the activity will appear on in the activity view. UIActivityCategoryShare puts the activity on the 1st row and UIActivityCategoryAction puts it on the 2nd row.
You can check the sample Code :https://github.com/ArpitLokwani/ALCustomActivityView
Related
My app receives a measurement every minute. When the measurement is 0, I want a label to be displayed in the middle. When it is greater than that, when I want the label to disappear. The issue I have is that once the label appears, it doesn't hide once I set its hidden mode to true.
UILabel *emptyBagLabel = [[UILabel alloc] init];
emptyBagLabel.textAlignment = NSTextAlignmentCenter;
emptyBagLabel.textColor = [UIColor darkGrayColor];
emptyBagLabel.numberOfLines = 0;
emptyBagLabel.text = #"EMPTY POUCH";
emptyBagLabel.translatesAutoresizingMaskIntoConstraints = NO;
emptyBagLabel.hidden = true;
[self addSubview:emptyBagLabel];
[emptyBagLabel.centerXAnchor constraintEqualToAnchor:self.centerXAnchor].active = YES;
[emptyBagLabel.centerYAnchor constraintEqualToAnchor:self.centerYAnchor].active = YES;
[emptyBagLabel.widthAnchor constraintEqualToAnchor:self.widthAnchor].active = YES;
[emptyBagLabel.heightAnchor constraintEqualToConstant:100].active= YES;
if (measurement == 0 || measurement <= 0.005) {
emptyBagLabel.hidden = false;
}
if (measurement > 0.005) {
emptyBagLabel.hidden = true;
}
I've been scratching my head at this for a while, a bit frustrated with how I'm not able to solve such a trivial issue. The method I have it in is called every minute. I know the method and the hidden = true line are getting called, so I'm unsure as to what is causing the issue.
Subview that are added programmatically ought to be added lazily, so you get exactly one subview instance. I'd refactor the code like this...
- (UILabel *)emptyBagLabel {
UILabel *emptyBagLabel = (UILabel *)[self.view viewWithTag:128];
if (!emptyBagLabel) {
emptyBagLabel = [[UILabel alloc] init];
emptyBagLabel.tag = 128;
// set all of the attributes her for how the label looks, textColor, etc.
// everything except the properties that change over time
[self addSubview:emptyBagLabel];
}
return emptyBagLabel;
}
// if this view is built using initWithFrame...
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self emptyBagLabel]; // to add the label initially
}
return self;
}
// if this view is ever loaded from a nib, then
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
[self emptyBagLabel];
}
return self;
}
// elsewhere in the view, when you get the measurement
// side note: alpha is usually a better choice than hidden because you can animate it
if (measurement == 0 || measurement <= 0.005) {
self.emptyBagLabel.alpha = 1.0;
}
if (measurement > 0.005) {
self.emptyBagLabel.alpha = 0.0;
}
I have a double-tap gesture on a view controller iRpImageViewerViewController (topmost on the navigation stack), and each time a view on iRpImageViewerViewController is double-tapped, it pushes a image editor view controller iRpImageEditorViewController onto the stack, that's why there are several of them, none of which appeared. Each time I double-tap, it's added, but never appears. self is simply the class that houses this double-tap gesture iRpImageViewerViewController, and does in fact have a navigationController per the LLDB output
po self.navigationController returns a navigation controller as expected.
po self.navigationController viewControllers shows a new view controller being added to the list with each pushViewController statement encountered, yet the pushed item won't show up on screen.
I shouldn't have to push and then move to front, right?? Doesn't the push automatically make it the frontmost view controller?
Note that my navigation controller is NOT the root controller in my hierarchy, starting from the window. I have a full screen map view controller, then a half-screen 'dashboard' view controller, then within that I have a window on the dashboard that has a picture, and that picture is itself a view controller. So starting with the picture view controller, shown here, you can walk through everything that happens
#implementation iRpDashboardHeaderImagesViewController
{
IGGridView *theGridViewControl;
UIView *theGridParentView;
iRpImageSet *thePropertyImageSet;
iRpDashboardViewController *dashboardViewController;
UIImageView *primaryImageMarker;
UINavigationController *imageEditorNavController;
iRpImageViewerViewController *imageViewerVC;
}
-(id)initWithParentViewController:(iRpDashboardViewController*)parentController
{
self = [super init];
if (self)
{
dashboardViewController = parentController;
}
return self;
}
-(void)loadView
{
// Just a basic size to get started... the final size is set later in another method. I believe actual height will be 220
CGRect theGridRectangle = CGRectMake(0, 0, 375, 220);
theGridViewControl = [[IGGridView alloc]initWithFrame:theGridRectangle style:IGGridViewStyleSingleCellPaging];
// Set additional properties to configure the grid view
theGridViewControl.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
theGridViewControl.selectionType = IGGridViewSelectionTypeCell;
theGridViewControl.contentMode = UIViewContentModeScaleAspectFit;
theGridViewControl.allowHorizontalBounce = NO;
theGridViewControl.alwaysBounceVertical = NO;
self.view = theGridViewControl;
}
-(void)viewDidLoad
{
[super viewDidLoad];
imageEditorNavController = [[UINavigationController alloc] init];
}
-(void)presentImageViewerForCellAtPath:(IGCellPath*)path
{
iRpImageAndMedia *imageAndMediaItem = [thePropertyImageSet objectAtIndex:path.columnIndex];
imageViewerVC = [[iRpImageViewerViewController alloc] initWithParentViewController:self imageSet:thePropertyImageSet initialImageAndMedia:imageAndMediaItem];
imageViewerVC.edgesForExtendedLayout = UIRectEdgeNone;
imageViewerVC.navigationItem.title = dashboardViewController.parcelNbr;
imageViewerVC.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(imageEditorDone)];
// Create a navigation controller to embed the image viewer view controller inside.
[imageEditorNavController pushViewController:imageViewerVC animated:YES];
[self presentViewController:imageEditorNavController animated:YES completion:^(void)
{
}];
}
-(void)imageEditorDone
{
[self dismissViewControllerAnimated:YES completion:^{}];
}
}
...
#implementation iRpImageViewerViewController
{
IGGridView *theMainImageGridviewControl;
iRpImageSet *thePropertyImageSet;
iRpImageFilmstripViewController *theFilmstripViewController;
iRpImageAndMedia *initialMediaItem;
UIImageView *primaryImageMarker;
iRpImageEditorViewController *imageEditorVC;
UIViewController *theParentViewController;
}
-(id)initWithParentViewController:(UIViewController*)parentViewController imageSet:(iRpImageSet*)imageSet initialImageAndMedia:(iRpImageAndMedia*)imageAndMedia
{
self = [super initWithNibName:#"iRpImageViewerViewController" bundle:nil];
if (self)
{
theParentViewController = parentViewController;
theFilmstripViewController = [[iRpImageFilmstripViewController alloc] initWithParentViewController:self imageSet:imageSet initialImageAndMedia:imageAndMedia];
initialMediaItem = imageAndMedia;
thePropertyImageSet = imageSet;
}
return self;
}
-(void)viewDidLoad
{
[super viewDidLoad];
theMainImageGridviewControl = [[IGGridView alloc]initWithFrame:self.mainImagePlaceholderView.frame style:IGGridViewStyleSingleCellPaging];
// Set additional properties to configure the grid view
theMainImageGridviewControl.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
theMainImageGridviewControl.selectionType = IGGridViewSelectionTypeCell;
theMainImageGridviewControl.contentInset = UIEdgeInsetsZero;
theMainImageGridviewControl.allowHorizontalBounce = NO;
theMainImageGridviewControl.alwaysBounceHorizontal = NO;
theMainImageGridviewControl.alwaysBounceVertical = NO;
[self.mainImagePlaceholderView addSubview:theMainImageGridviewControl];
[self addAChildViewController:theFilmstripViewController toViewWithTag:self.filmstripPlaceholderView.tag];
}
-(void)addGestureRecognizersToCell:(IGGridViewImageCell*)cell
{
static NSMutableArray *recognizers;
UITapGestureRecognizer *doubleTapRecognizer;
UILongPressGestureRecognizer *longPressRecognizer;
if (!recognizers)
{
recognizers = [[NSMutableArray alloc] init];
doubleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleDoubleTapRecognizer:)];
doubleTapRecognizer.numberOfTapsRequired = 2;
longPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(handleLongPressRecognizer:)];
[recognizers addObject:doubleTapRecognizer];
[recognizers addObject:longPressRecognizer];
}
// Don't do anything because already processed.
[cell removeGestureRecognizer:doubleTapRecognizer];
[cell removeGestureRecognizer:longPressRecognizer];
[cell registerGestures:recognizers];
}
-(void)handleDoubleTapRecognizer:(UITapGestureRecognizer*)recognizer
{
NSLog(#"Double Tapped on ImageViewerViewController's main image, so opening editor");
IGCellPath *pathForCurrentCell = [self pathForCurrentCell];
iRpImageAndMedia *imageAndMediaItem = [thePropertyImageSet objectAtIndex:pathForCurrentCell.columnIndex];
imageEditorVC = [[iRpImageEditorViewController alloc] initWithImageAndMediaItem:imageAndMediaItem];
imageEditorVC.navigationItem.title = #"Photo Details Editor";
imageEditorVC.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(imageEditorDone)];
imageEditorVC.edgesForExtendedLayout = UIRectEdgeNone;
[self.navigationController pushViewController:imageEditorVC animated:YES];
}
-(void)imageEditorDone
{
[self.navigationController popToRootViewControllerAnimated:YES];
}
-(void)imageEditorCancelled
{
[self dismissViewControllerAnimated:YES completion:nil];
}
}
...
This class below is the one that keeps being added to the navigation controller, but never appears.
...
#implementation iRpImageEditorViewController
{
__weak IBOutlet UISwitch *primarySwitch;
__weak IBOutlet UISwitch *postToWebSwitch;
__weak IBOutlet UITextView *descriptionView;
__weak IBOutlet UIImageView *imageView;
__weak IBOutlet UITextField *mediaDate;
__weak IBOutlet UITextField *orderNbr;
__weak IBOutlet UITextField *updatedBy;
__weak IBOutlet UITextField *updateDate;
iRpImageAndMedia *theImageAndMediaItem;
}
-(id)initWithImageAndMediaItem:(iRpImageAndMedia*)imageAndMediaItem
{
if (self = [super initWithNibName:#"iRpImageEditorViewController" bundle:nil])
{
theImageAndMediaItem = imageAndMediaItem;
}
return self;
}
-(void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
[self populateUserInterface];
}
-(void)populateUserInterface
{
imageView.image = [theImageAndMediaItem pictureForViewOfSize:imageView.bounds.size];
primarySwitch.on = [theImageAndMediaItem isPrimary];
postToWebSwitch.on = [[theImageAndMediaItem.mediaManagedObj valueForKey:#"postToWeb"] boolValue];
descriptionView.text = [theImageAndMediaItem.mediaManagedObj valueForKey:#"desc"];
updatedBy.text = [theImageAndMediaItem.mediaManagedObj valueForKey:#"updatedBy"];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"MM/dd/yyyy"];
[dateFormat setTimeZone:[NSTimeZone localTimeZone]];
NSString *theFormattedDate = [dateFormat stringFromDate:[theImageAndMediaItem.mediaManagedObj valueForKey:#"updateDate"]];
updateDate.text = theFormattedDate;
orderNbr.text = [[theImageAndMediaItem.mediaManagedObj valueForKey:#"order"] stringValue];
}
-(IBAction)postToWebValueChanged:(id)sender
{
UISwitch *theSwitch = sender;
[theImageAndMediaItem.mediaManagedObj setValue:[NSNumber numberWithBool:theSwitch.on] forKey:#"postToWeb"];
}
-(IBAction)primaryValueChanged:(id)sender
{
UISwitch *theSwitch = sender;
[theImageAndMediaItem.mediaManagedObj setValue:[NSNumber numberWithBool:theSwitch.on] forKey:#"primary"];
}
...
-(void)handleDoubleTapRecognizer:(UITapGestureRecognizer*)recognizer
{
NSLog(#"Double Tapped on ImageViewerViewController's main image, so opening editor");
IGCellPath *pathForCurrentCell = [self pathForCurrentCell];
iRpImageAndMedia *imageAndMediaItem = [thePropertyImageSet objectAtIndex:pathForCurrentCell.columnIndex];
imageEditorVC = [[iRpImageEditorViewController alloc] initWithImageAndMediaItem:imageAndMediaItem];
imageEditorVC.navigationItem.title = #"Photo Details Editor";
imageEditorVC.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(imageEditorDone)];
imageEditorVC.edgesForExtendedLayout = UIRectEdgeNone;
[self.navigationController pushViewController:imageEditorVC animated:YES];
}
I have a UITableView inside of an UITabBarController. Now, I am already checking to see if a user is logged in, and if they are not logged in I display a Modal View Controller to have them log in or sign up. But here's my problem, when the user hit's cancel, the user goes back to the original position of the table view. I can't have users see the rows in table view if they are not signed in. If a user is not logged in, I want a message exactly how the examples Apple gives in the iTunes store and the "Popular near me" examples in the Apple Human Interface Guideline:
https://developer.apple.com/library/iOS/documentation/userexperience/conceptual/mobilehig/StartingStopping.html#//apple_ref/doc/uid/TP40006556-CH52-SW1
So how would I display a message like that in a tableview controller? Keep in mind, I will always have data for that table view controller. Hopefully I am clear for everyone. Would I just bring the tableview background to the front of the tableview rows?
// ATableViewController embedded in a NavigationController with UITabBar
- (void)viewWillAppear:(BOOL)animated
{
// NSLog(#"dateViewDidLoad %f", [[NSDate date] timeIntervalSince1970]);
[super viewWillAppear:animated];
NSUserDefaults *textDef = [NSUserDefaults standardUserDefaults];
NSString *userName = [textDef stringForKey:#"userName"];
if (userName == nil) {
SignUpViewController *signup = [[SignUpViewController alloc]initWithNibName:#"SignUpViewController" bundle:nil];
[signup setModalTransitionStyle:UIModalTransitionStyleCoverVertical];
[self presentViewController:signup animated:YES completion:nil];
// Display message you need to sign in to view this content
} else {
// Proceed and display the rows
}
}
If you use a UITableViewController you could "abuse" tableHeaderView of the tableView, by resizing it to full screen and disabling the dataSource methods and scrolling.
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if (isLoggedIn) {
self.tableView.tableHeaderView = nil;
self.tableView.delegate = self;
self.tableView.dataSource = self;
self.tableView.scrollEnabled = YES;
[self.tableView reloadData];
}
else {
if (!self.tableView.tableHeaderView) {
UIView *viewToDisplayIfNotLoggedIn = [[UIView alloc] initWithFrame:self.view.bounds];
viewToDisplayIfNotLoggedIn.backgroundColor = [UIColor redColor];
self.tableView.tableHeaderView = viewToDisplayIfNotLoggedIn;
}
self.tableView.delegate = nil;
self.tableView.dataSource = nil;
self.tableView.scrollEnabled = NO;
[self.tableView reloadData];
}
}
If you are using a normal UIViewController it's even easier than that, just hide the tableView and show another UIView:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if (isLoggedIn) {
self.tableView.hidden = NO;
self.viewToDisplayIfNotLoggedIn.hidden = YES;
}
else {
self.tableView.hidden = YES;
if (!self.viewToDisplayIfNotLoggedIn) {
self.viewToDisplayIfNotLoggedIn = [[UIView alloc] initWithFrame:self.view.bounds];
self.viewToDisplayIfNotLoggedIn.backgroundColor = [UIColor redColor];
[self.view addSubview:self.viewToDisplayIfNotLoggedIn];
}
self.viewToDisplayIfNotLoggedIn.hidden = NO;
}
}
I have a UITableView which has some custom styling. This table view appears in two places in the app, one of which is inside a UIPopoverController. However when the tableview is inside the popover it takes on the default tableview styling as stated in the UI Transition Guide under "Popover".
The problem I have is that there appears to be nowhere to change this behaviour. Regardless of where I try and modify properties of the tableview the view inside the popover doesn't change.
Anyone dealt with this issue before or have any ideas?
Here is the init method of LibraryProductView where I create the table view:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.sectionOrdering = [NSArray arrayWithObjects:
[NSNumber numberWithInt:LIBRARY_PRODUCT_SECTION_DESCRIPTION],
[NSNumber numberWithInt:LIBRARY_PRODUCT_SECTION_DOCUMENTS],
[NSNumber numberWithInt:LIBRARY_PRODUCT_SECTION_ACTIVE_INGREDIENTS],
[NSNumber numberWithInt:LIBRARY_PRODUCT_SECTION_RELATED_PRODUCTS],
[NSNumber numberWithInt:LIBRARY_PRODUCT_SECTION_RELATED_DOCUMENTS], nil];
self.backgroundColor = [UIColor whiteColor];
self.tableView = [[UITableView alloc] initWithFrame:CGRectInset(self.bounds, 10, 0) style:UITableViewStyleGrouped];
self.tableView.backgroundColor = [UIColor whiteColor];
self.tableView.dataSource = self;
self.tableView.delegate = self;
self.tableView.separatorColor = [UIColor clearColor];
self.tableView.showsVerticalScrollIndicator = NO;
[self addSubview:self.tableView];
}
return self;
}
Here is where the containing view (LibraryProductView) is added to the popover:
- (IBAction)didTouchInformationButton:(id)sender
{
if (_infoPopover != nil && _infoPopover.isPopoverVisible)
{
[_infoPopover dismissPopoverAnimated:YES];
return;
}
CGSize preferredSize = CGSizeMake(600.0f, 500.0f);
LibraryProductViewController* productController = [[[LibraryProductViewController alloc] initWithPreferredSize:preferredSize] autorelease];
productController.filterByMyCompany = NO;
productController.product = _activityInput.product;
UINavigationController* nav = [[[UINavigationController alloc] initWithRootViewController:productController] autorelease];
nav.title = _activityInput.product.name;
RELEASE(_infoPopover);
_infoPopover = [[UIPopoverController alloc] initWithContentViewController:nav];
_infoPopover.popoverContentSize = CGSizeMake(preferredSize.width, preferredSize.height + 46);
[_infoPopover presentPopoverFromRect:_infoButton.frame inView:_infoButton permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];
}
The LibraryProductView is created within viewDidLoad method of LibraryProductViewController.
- (void)viewDidLoad
{
[super viewDidLoad];
self.libraryProductView = [[LibraryProductView alloc] initWithFrame:(usingPreferredSize ? CGRectMake(0.0, 0.0, preferredSize.width, preferredSize.height) : self.view.bounds)];
self.libraryProductView.dataSource = self;
self.libraryProductView.delegate = self;
[self.view addSubview:self.libraryProductView];
}
To set properties for the TableView you might do so in
- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
[tableView setBackgroundColor:[UIColor redcolor]];
[tableView setSeparatorColor: [UIColor blueColor]];
return 1;
}
This, of course, assumes you have set UITableViewDataSource in your .h file
I'm trying to create a UISearchDisplayController programmatically. I have a method which should set up my search controller, but when I call it, nothing happens.
This my -setupSearch method:
- (void)setupSearch {
UISearchBar *myBar;
UISearchDisplayController *myCon;
myBar = [[UISearchBar alloc] initWithFrame:CGRectZero];
[myBar sizeToFit];
myCon = [[UISearchDisplayController alloc]
initWithSearchBar:myBar contentsController:self];
[myBar release];
myCon.delegate = self;
myCon.searchResultsDataSource = self;
myCon.searchResultsDelegate = self;
/* Setup scopes */
{
NSMutableArray *scopes;
NSUInteger count, i;
NSString *aScope;
count = SCOPE_COUNT;
scopes = [[NSMutableArray alloc] initWithCapacity:count];
for(i = 0; i < count; i++) {
// I create four scopes here
}
myCon.searchBar.scopeButtonTitles = scopes;
[scopes release];
}
[myCon release];
}
I call the above method in the -viewDidLoad method of my subclassed UITableViewController. Unfortunately nothing happens when my table view controller get's displayed in a UITabBarController.
Any help would be greatly appreciated.
Check out the example code in:
[https://github.com/JayMarshal/GrabCasts.com-iPhone-Client/blob/master/CoreDataTableViewController.m][1]
Repo here: https://github.com/JayMarshal/Grabcasts
It is an expanded version of the coredatatableviewcontroller of the stanford iOS courses.
Relevant snippet of that code follows:
- (void)createSearchBar {
if (self.searchKey.length) {
if (self.tableView && !self.tableView.tableHeaderView) {
UISearchBar *searchBar = [[[UISearchBar alloc] init] autorelease];
self.searchDisplayController
= [[UISearchDisplayController alloc] initWithSearchBar:searchBar
contentsController:self];
self.searchDisplayController.searchResultsDelegate = self;
self.searchDisplayController.searchResultsDataSource = self;
self.searchDisplayController.delegate = self;
searchBar.frame = CGRectMake(0, 0, 0, 38);
self.tableView.tableHeaderView = searchBar;
}
} else {
self.tableView.tableHeaderView = nil;
}
Basically it attaches the UISearchDisplayController to self (which must be a tableviewcontroller) as a side effect of the initialization. So setting:
self.searchDisplayController.searchResultsDelegate = self;
self.searchDisplayController.searchResultsDataSource = self;
Instead of
myCon.searchResultsDataSource = self;
myCon.searchResultsDelegate = self;
Might do the trick. In debugging, check whether myCon and self.searchDisplayController are pointing to the same object?
Updated: there seems to be a bug in the SDC property of the TVC that it is not retained in the runloop. Filed as: http://openradar.appspot.com/10254897 also mentioned on SO, see
UIViewController does not retain its programmatically-created UISearchDisplayController