在特定日期重复 UILocalNotification

Posted

技术标签:

【中文标题】在特定日期重复 UILocalNotification【英文标题】:Repeat UILocalNotification on Specific day 【发布时间】:2014-02-24 06:15:42 【问题描述】:

我需要设置 UILocalNotification,我只需要从 DatePicker 中获取小时和分钟,并且需要设置特定的日期(例如:星期一)并在每个星期一重复。

我有两个问题:

第一个;是否可以在日期选择器的日期部分仅显示“星期天”之类的“日期名称”?

第二个问题是;如果我想为本地通知设置特定日期,正确的代码是什么?

感谢您的回答,下面是我的代码;

-(IBAction) alarmButton:(id)sender 

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
dateFormatter.timeZone = [NSTimeZone defaultTimeZone];
dateFormatter.timeStyle = NSDateFormatterShortStyle;
dateFormatter.dateStyle = NSDateFormatterShortStyle;

NSString *dateTimeString = [dateFormatter stringFromDate: dateTimePickerSet1.date];
NSLog ( @"Alarm Set :%@" , dateTimeString);

[self scheduleLocalNotificationWithDate1: dateTimePickerSet1.date];



-(void)scheduleLocalNotificationWithDate1:(NSDate *)fireDate 
UILocalNotification *notification = [[UILocalNotification alloc] init];

notification.fireDate = fireDate;
notification.alertBody = @"Alarm Set !";

[[UIApplication sharedApplication] scheduleLocalNotification:notification];

【问题讨论】:

检查 - useyourloaf.com/blog/2010/09/13/… 或者您也可以从 ***.com/questions/14769462/… 或 ***.com/questions/18014438/… 获得一些帮助 【参考方案1】:

问题 1 => 我不明白你想要什么。 (但如果您只想显示日期名称,例如星期日、星期一、....到星期六,请使用UIPickerView.

问题 2 => 您可以获得特定日期的正确日期,并且您可以在每个特定日期收到通知 /em> 设置localNotification.repeatInterval = NSWeekCalendarUnit;

为了实现它,还需要使用下面的(method's)代码。此方法将返回特定选定日期的正确日期,您只需将 day 作为方法的参数传递,例如,

如果所选日期是星期日,则通过1 如果选择的日期是 星期一,则通过 2 . . . 如果所选日期是星期六,则通过 7

这是方法代码:

-(NSDate *) getDateOfSpecificDay:(NSInteger ) day /// here day will be 1 or 2.. or 7

  NSInteger desiredWeekday = day
  NSRange weekDateRange = [[NSCalendar currentCalendar] maximumRangeOfUnit:NSWeekdayCalendarUnit];
  NSInteger daysInWeek = weekDateRange.length - weekDateRange.location + 1;

  NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:NSWeekdayCalendarUnit fromDate:[NSDate date]];
  NSInteger currentWeekday = dateComponents.weekday;
  NSInteger differenceDays = (desiredWeekday - currentWeekday + daysInWeek) % daysInWeek;
  NSDateComponents *daysComponents = [[NSDateComponents alloc] init];
  daysComponents.day = differenceDays;
  NSDate *resultDate = [[NSCalendar currentCalendar] dateByAddingComponents:daysComponents toDate:[NSDate date] options:0];
  return resultDate;

别忘了设置localNotification.repeatInterval = NSWeekCalendarUnit;

【讨论】:

非常感谢您的回复,但我需要更多关于答案号的帮助:2. 是否可以获得一些关于如何将您的答案与日期选择器配置一起使用的示例代码?我不太确定我必须在哪里实现这个:(再次非常感谢@iPatel 在花了几个小时了解您的方法后,我实施了它,现在它完美运行!谢谢@iPatel。 @Rick 为什么当我在 7-Sunday 安装 fireDate 时,我的通知每天都会出现在当前时间,但我设置为 7-Sunday,已经尝试了 4 个具有相同代码的示例,但没有一个好的解决方案,我是什么做错了吗?【参考方案2】:

这是@iPatel 的解决方案,它还考虑了通过日期选择器传入的时间组件。 (我还更新了他的解决方案以使用未弃用的最新日历单位)。

- (NSDate *) getFireDateForDayOfWeek:(NSInteger)desiredWeekday withTime:(NSDate *)time // 1:Sunday - 7:Saturday

    NSRange weekDateRange = [[NSCalendar currentCalendar] maximumRangeOfUnit:NSCalendarUnitWeekday];
    NSInteger daysInWeek = weekDateRange.length - weekDateRange.location + 1;

    NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:NSCalendarUnitWeekday fromDate:[NSDate date]];
    NSInteger currentWeekday = dateComponents.weekday;
    NSInteger differenceDays = (desiredWeekday - currentWeekday + daysInWeek) % daysInWeek;

    NSDateComponents *daysComponents = [[NSDateComponents alloc] init];
    daysComponents.day = differenceDays;
    NSDate *fireDate = [[NSCalendar currentCalendar] dateByAddingComponents:daysComponents toDate:[NSDate date] options:0];

    NSDateComponents *timeComponents = [[NSCalendar currentCalendar] components:     NSCalendarUnitHour | NSCalendarUnitMinute fromDate:time];
    NSDateComponents *fireDateComponents = [[NSCalendar currentCalendar]
                components: NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond
                fromDate:fireDate];

    fireDateComponents.hour = timeComponents.hour;
    fireDateComponents.minute = timeComponents.minute;
    fireDateComponents.second = 0;

    NSDate *resultDate = [[NSCalendar currentCalendar] dateFromComponents:fireDateComponents];

    // The day could be today but time is in past. If so, move ahead to next week
    if(resultDate.timeIntervalSinceNow < 0) 
        resultDate = [resultDate dateByAddingTimeInterval:60 * 60 * 24 * 7];
    

    return resultDate;

【讨论】:

欧伦,你好吗?在过去的几个小时里,我试图理解你的代码,这正是我需要的,但它似乎不起作用。请尽快与我联系,我已经做了 3 天的工作,但仍然没有弄清楚这个简单的部分,哈哈。 Toda Ahi :) muliastudios@gmail.com【参考方案3】:

这个解决方案也需要时间,但比 Oren 的要简单一些

-(NSDate *) dateOfSpecificDay:(NSInteger ) day withFireTime:(NSDate *)timeDate/// here day will be 1 or 2.. or 7 and timeDate the current day with the desired time 

    NSInteger desiredWeekday = day;
    NSRange weekDateRange = [[NSCalendar currentCalendar] maximumRangeOfUnit:NSCalendarUnitWeekday];
    NSInteger daysInWeek = weekDateRange.length - weekDateRange.location + 1;

    NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:NSCalendarUnitWeekday fromDate:[NSDate date]];
    NSInteger currentWeekday = dateComponents.weekday;
    NSInteger differenceDays = (desiredWeekday - currentWeekday + daysInWeek) % daysInWeek;
    if (differenceDays == 0) 
        //Check if should register for same day or for next week
        if ([timeDate compare:[NSDate date]] == NSOrderedAscending) 
            //Should schedule for next week
            differenceDays = daysInWeek;
        
    

    NSDateComponents *daysComponents = [[NSDateComponents alloc] init];
    daysComponents.day = differenceDays;
    NSDate *resultDate = [[NSCalendar currentCalendar] dateByAddingComponents:daysComponents toDate:timeDate options:0];

    return resultDate;

【讨论】:

【参考方案4】:

这是 swift 版本:

func calculateTheNExtFriday(inputTime: NSDate) -> NSDate 
    let desiredWeekday = 6 // Friday

    let weekDateRange = NSCalendar.currentCalendar().maximumRangeOfUnit(NSCalendarUnit.Weekday)
    let daysInWeek = weekDateRange.length - weekDateRange.location + 1;

    let currentWeekday = NSCalendar.currentCalendar().components(NSCalendarUnit.Weekday, fromDate: inputTime).weekday
    let differenceDays = (desiredWeekday - currentWeekday + daysInWeek) % daysInWeek

    let dateComponents = NSDateComponents()
    dateComponents.day = differenceDays

    let calculatedFridayDate = NSCalendar.currentCalendar().dateByAddingComponents(dateComponents, toDate: inputTime, options: NSCalendarOptions.init(rawValue: 0))
    return calculatedFridayDate!

在本例中,我在函数中使用了desiredWeekday,但您也可以将其用作参数。

注意:请记住,第 1 天对应于星期日、2 -> 星期一和 以此类推

【讨论】:

【参考方案5】:

斯威夫特 3:

func calculateSpecificDay(_ desiredWeekday: NSInteger, fromDate: Date = Date()) -> Date 

    let weekDateRange = NSCalendar.current.maximumRange(of: .weekday)!
    let daysInWeek = weekDateRange.lowerBound.distance(to: weekDateRange.upperBound) - weekDateRange.lowerBound + 1

    let currentWeekday = NSCalendar.current.dateComponents([.weekday], from: fromDate).weekday
    let differenceDays = (desiredWeekday - currentWeekday! + daysInWeek) % daysInWeek

    var dateComponents = DateComponents()
    dateComponents.day = differenceDays

    let calculatedFridayDate = NSCalendar.current.date(byAdding: dateComponents, to: fromDate)
    return calculatedFridayDate!

If selected day is sunday then pass 1
If selected day is monday then pass 2
.
.
.
If selected day is saturday then pass 7

【讨论】:

以上是关于在特定日期重复 UILocalNotification的主要内容,如果未能解决你的问题,请参考以下文章

Java:检查当前日期是不是在特定日期范围内[重复]

在特定时区生成日期[重复]

iOS 10:如何在特定日期触发后重复本地通知?

SQL在特定日期选择重复项

斯威夫特:在“特定日期”之前获得 30 天 [重复]

在 LINQ 中按特定列分组 [重复]